TA: Kingdoms Community Forum
 
HomePortalCalendarGalleryFAQSearchMemberlistUsergroupsRegisterLog in

Share | 
 

 Wqaopl's tnt maker

View previous topic View next topic Go down 
Go to page : 1, 2  Next
AuthorMessage
$_Spagg

avatar

Posts : 387
Reputation : 16
Join date : 2010-10-31
Age : 104
Location : Brazil

PostSubject: Wqaopl's tnt maker   Tue Aug 02, 2016 4:04 pm

Wqapol still around?
Mind sharing any info on interpreting .tnt road/item maps on tnt files?
I've been messing around with tnt file from kmp lately and I got to render all of the map info (including palette support) except roadmap and item positions.
Upon doing some research I found TNT Maker by wqaopl which displays them correctly (downloaded at alltakdownloads henrique site)

And in that tool Wqaopl got them right (although minimap and tabmap arent finished) so mind if we trade some knowledge Smile ?
I see you were using greyscale to render the minimap and big minimap and in the README you mention you still need to do research on how to implement the color palettes. I did greyscale for the heightmap too:

But for the minimap and big minimap I managed to decode the palettes and this was the result:
and
My poor attempt at rendering the road/itemmaps (?):


Anyway to get the palette just grab the .pcx file for the map race (ex: taros.pcx) and skip to offset 0x84 and read from there in RGB order (3 bytes per color) and the palette has 256 colors (so 768 bytes total) and you just access eachcolor normally by indexing to the palette


Last edited by $_Spagg on Wed Aug 03, 2016 6:50 pm; edited 3 times in total
Back to top Go down
View user profile
$_Spagg

avatar

Posts : 387
Reputation : 16
Join date : 2010-10-31
Age : 104
Location : Brazil

PostSubject: Re: Wqaopl's tnt maker   Tue Aug 02, 2016 4:07 pm

Edit: I dunno what the other values signify in the .pcx file, I just skipped bytes until something worked!

Aalso this means it should be easy to change the palette too since theyre just in raw RGB order. Proof: https://i.imgur.com/kiy9Qg0.png

Edit- the palette size is actually 256 since the length of the file from 0x84 to the end of the file is 768 (768 / 3 = 256), not 255 (miscalculated that part, was wondering what would happen with a color index of 255)
Back to top Go down
View user profile
rammstein

avatar

Posts : 73
Reputation : 4
Join date : 2010-04-16
Age : 25
Location : Sweden

PostSubject: Re: Wqaopl's tnt maker   Wed Aug 03, 2016 7:07 pm

It was some time since I last worked with tnt files, but I think I used the following post on TA Universe for help: http://www.tauniverse.com/forum/showthread.php?t=23627

Maybe it will be of use for you.
Back to top Go down
View user profile
$_Spagg

avatar

Posts : 387
Reputation : 16
Join date : 2010-10-31
Age : 104
Location : Brazil

PostSubject: Re: Wqaopl's tnt maker   Thu Aug 04, 2016 9:17 am

That was a very helpful read, thanks for the link
Back to top Go down
View user profile
Wqaopl

avatar

Posts : 212
Reputation : 0
Join date : 2008-08-14

PostSubject: Re: Wqaopl's tnt maker   Fri Aug 05, 2016 6:51 am

sorry i did not see your post for ages

the tnt file is quite simple ish lets see if i can remeber whow it goes
struct TNTHEDDER{
DWORD FileID;
DWORD Width;
DWORD Height;
DWORD SeaLevel;
DWORD LHeightMap;
DWORD LAttributes;
DWORD LFeatureNames;
DWORD FeaturesNb;
DWORD LTerrainNames;
DWORD LUmapping;
DWORD LVmapping;
DWORD LSmallMiniMap;
DWORD LBigMiniMap;
};

LHeightMap is a one byte gray scale using width * hight for size
LAttributes is a two byte map of objects using width * hight for size the values of 65531 and 65535 are the road map and blocking map. the other valuse map to the feature list.

LFeatureNames is a 132 byte char string with FeaturesNb providing the nuber of names
LTerrainNames i a 4 byte list using width * hight for size and corasponds to the bitmap images in the hpi files

the uv map is the 32 pixel offset? in the terrain bitmap and is each a one byte list the size of each is (width /2)*(hight/2)


for the mini maps the first 8 bytes are the with and hight respectively with a 4 byte bitmap

if you want a better anser looking at the tnt file itself wil probably yeals better ansers =) but i hope this helps.

_________________
There are loads of modern ideas but new ideas are rare.
Back to top Go down
View user profile
$_Spagg

avatar

Posts : 387
Reputation : 16
Join date : 2010-10-31
Age : 104
Location : Brazil

PostSubject: Re: Wqaopl's tnt maker   Mon Aug 08, 2016 3:14 pm

^
Yep, that helps, even though I already had most of the header figured out (the pictures from the post at the top that I generated with C++)
Except for the "features" part which should be easy now with your post and rammenstein's
I had no idea the word the at 0x0C was for the sea height also (since even maps without any water seem to have sea height too), I'm looking into what does that even do or how the sea height affects the map
Anyway soon my desktop kmp visualiser will be alive
Back to top Go down
View user profile
Vhaerun

avatar

Posts : 111
Reputation : 12
Join date : 2014-01-12
Age : 37
Location : VA, USA

PostSubject: Re: Wqaopl's tnt maker   Mon Aug 08, 2016 3:53 pm

Some good work and knowledge. Also, you two should try your minds at making a TAF editing/making program much like GafBuilder. If you do decide to try and make a TAF editor, I can point you to the relevent information if you do not know it.

_________________
" Boys have swag,
Men have style,
Gentlemen have class!"

-- Vaerun
Back to top Go down
View user profile
Wqaopl

avatar

Posts : 212
Reputation : 0
Join date : 2008-08-14

PostSubject: Re: Wqaopl's tnt maker   Mon Aug 08, 2016 4:24 pm

my next aim was to try and use hpi file so i could make a map editer with a full rainge of options, help i needed =(

_________________
There are loads of modern ideas but new ideas are rare.
Back to top Go down
View user profile
Vhaerun

avatar

Posts : 111
Reputation : 12
Join date : 2014-01-12
Age : 37
Location : VA, USA

PostSubject: Re: Wqaopl's tnt maker   Mon Aug 08, 2016 4:36 pm

Much like TA's Annihilator map making program?

_________________
" Boys have swag,
Men have style,
Gentlemen have class!"

-- Vaerun
Back to top Go down
View user profile
$_Spagg

avatar

Posts : 387
Reputation : 16
Join date : 2010-10-31
Age : 104
Location : Brazil

PostSubject: Re: Wqaopl's tnt maker   Mon Aug 08, 2016 4:39 pm

- Vhaerun

I dont know much about the GAF builder (I dont even remember what is a "TAF") what would be the changes between the existing GAF builder and the new one? I like the idea but i haven't used the GAF builder much in the past

- Wqaopl

I have an HPI reader function in C++ which im using to grab the TNT bytes directly from the kmp
The code is all in Qt C++ though...
I can post the source later if you want, although I should probably organize it better...

Since you talked about map editor, I tried making a map editor too, found way too confusing because of how strange the tiles are...
Spoiler:
 
Basically the source of my despair is that the width/height of the tile representation is disproportional, the map is organized in rows of tilenames (the ones in the terrain) and the real pixel dimension is different from the width and height, tiles are bigger in width than they are in height (probably to create the angular view in the game, since you don't actually see the map from the top to bottom, but kinda angled from the top to bottom, which is why the terrain representation is weird and the map ends up with smaller height than it should be)
Found too boring to wrap my head around it so i just moved to a next project
Back to top Go down
View user profile
Vhaerun

avatar

Posts : 111
Reputation : 12
Join date : 2014-01-12
Age : 37
Location : VA, USA

PostSubject: Re: Wqaopl's tnt maker   Mon Aug 08, 2016 4:54 pm

Gaf files are the animation files used mainly in TA; in TA:K, taf files are used which according to this post here at TAUniverse: Taf File format by Xon are basically gaf files but use a different compression and are 16 bit images versus 8 bit. The source code is here: GafBuilder1.2 but I do not know how to compile the source to make it execute.

_________________
" Boys have swag,
Men have style,
Gentlemen have class!"

-- Vaerun
Back to top Go down
View user profile
$_Spagg

avatar

Posts : 387
Reputation : 16
Join date : 2010-10-31
Age : 104
Location : Brazil

PostSubject: Re: Wqaopl's tnt maker   Mon Aug 08, 2016 5:11 pm

I see, once I finish KMP visualizer and HPI Tools (combination of hpi viewer and hpi pack in one program, with drag&drop facilities) I'd like to help with this
Back to top Go down
View user profile
Wqaopl

avatar

Posts : 212
Reputation : 0
Join date : 2008-08-14

PostSubject: Re: Wqaopl's tnt maker   Mon Aug 08, 2016 5:23 pm

i can see making a hightmap editer confusing but a map editer should start out just stiching TNT info together as its all the same thing and ment to fit together.

the hpi c++ code will help me whatever libary it uses the referance im using is just so slightly off.

as for a gaf/taf editer it looks like boring info/entry management and is back of the list of intrests =(

allthow i was planing on creating a program that delt with all the TAK files

_________________
There are loads of modern ideas but new ideas are rare.
Back to top Go down
View user profile
$_Spagg

avatar

Posts : 387
Reputation : 16
Join date : 2010-10-31
Age : 104
Location : Brazil

PostSubject: Re: Wqaopl's tnt maker   Mon Aug 08, 2016 5:34 pm

I dont have the full hpi code C++ on this machine (my map previewer is navigating the kmp directly and dirty, without fulyl reading the headers and skimming straight into the first .tnt HPI entry it finds)
But I have a java prototype which I make a long time ago: it's kinda dirty too but it should work (I used the HPI view as reference)
https://drive.google.com/file/d/0ByHfuH4MPaOXXzV0YnJMd1NTLWs/view?usp=sharing

As for the qt code I'm making a standalone version in parallel to an HPI tool program (which like I said above, is intended to make it easy to manipulate HPI files by combining both the ability to view HPIs and pack them back in one program) But that should take more time since I have the map thing as priority for now
Back to top Go down
View user profile
$_Spagg

avatar

Posts : 387
Reputation : 16
Join date : 2010-10-31
Age : 104
Location : Brazil

PostSubject: Re: Wqaopl's tnt maker   Mon Aug 08, 2016 5:39 pm

Also if you don't already have the source to HPI viewer you can download here: https://drive.google.com/open?id=0ByHfuH4MPaOXTXZKRGFFMEM4OGc
Back to top Go down
View user profile
Vhaerun

avatar

Posts : 111
Reputation : 12
Join date : 2014-01-12
Age : 37
Location : VA, USA

PostSubject: Re: Wqaopl's tnt maker   Mon Aug 08, 2016 9:10 pm

Understandable on the TAF program. When you get the time and are real bored Very Happy
Before Pocket Geek left us, he shared his version of HPI view which can read TAF files. I do not know if it is here or at one of the other sites, but it is HPI view 1.95pg. Now if you use that program to open data hpi or IPdata hpi and look in the anims folder, you can see how wonderful the TAF animations are.

As an aside here is a bit of code from Pocket geek's viewtaf.c:
//
// TAF Viewer Code
//

#include
#include
#include
#include
#include

#include "resource.h"
#include "hpiview.h"
#include "splitstuf.h"
#include "viewstuf.h"
#include "palette.h"

#pragma pack(1)

typedef struct _VIEWOPTION {
int option;
int Length;
int Version;
char *Name;
char *buff;
TAFHEADER *Header;
TAFENTRY *CurEntry;
TAFFRAMEENTRY *FrameEntry;
TAFFRAMEDATA **gfd;
HPALETTE hpal;
HDC hdc;
int CurFrame;
int xofs;
int yofs;
} VIEWOPTION;

#pragma pack()

const char ViewTafJpgWindowClass[] = "HPIViewTafJpg";
int ViewTafClassRegistered = FALSE;

void FreeFrameStuff(VIEWOPTION *vo)
{
if (vo->gfd) {
FreeMem(vo->gfd);
vo->gfd = NULL;
}
}

void FrameToHDC(HDC hdc, VIEWOPTION *vo, TAFFRAMEDATA *gfd)
{
unsigned char *frame;
int bcount;
int count;
int repeat;
unsigned char mask;
int xcount;
int ycount;
int y;
COLORREF *color;
int xofs = vo->xofs - gfd->XPos;
int yofs = vo->yofs - gfd->YPos;

frame = vo->buff + gfd->PtrFrameData;
switch (vo->Version) {
case HPI_V1 :
color = TAColor;
break;
case HPI_V2 :
color = TAKColor;
break;
default :
color = TAColor;
}
if (gfd->Compressed==1) {
for (ycount = 0; ycount < gfd->Height; ycount++) {
bcount = *((short *) frame);
frame += sizeof(short);
y = yofs + ycount;
xcount = xofs;
count = 0;
while (count < bcount) {
mask = (unsigned char) frame[count++];
if ((mask & 0x01) == 0x01) {
// transparent
xcount += (mask >> 1);
}
else if ((mask & 0x02) == 0x02) {
// repeat next byte
repeat = (mask >> 2) + 1;
while (repeat--) {
SetPixelV(hdc, xcount++, y, color[frame[count]]);

}
count++;
}
else {
repeat = (mask >> 2) + 1;
while (repeat--) {
SetPixelV(hdc, xcount++, y, color[frame[count++]]);
}
}
}
frame += bcount;
}
}
else if(gfd->Compressed==0){
for (ycount = 0; ycount < gfd->Height; ycount++) {
for (xcount = 0; xcount < gfd->Width; xcount++) {
SetPixelV(hdc, xcount+xofs, ycount+yofs, color[*frame++]);
}
}
}
else if(gfd->Compressed==4) {
COLORREF color=0; BYTE* pColor = (BYTE*)&color;
for (ycount = 0; ycount < gfd->Height; ycount++) {
for (xcount = 0; xcount < gfd->Width; xcount++){
// AAAARRRRBBBBGGGG
WORD pixel = *(WORD*)frame;
pColor[0] = (pixel & 0xF000) >> 8;
pColor[1] = (pixel & 0x00F0);
pColor[2] = (pixel & 0x000F) << 4;
pColor[3] = (pixel & 0xF000) >> 4;
if( pColor[0] )
SetPixelV(hdc, xcount+xofs, ycount+yofs, color );
frame += 2;
}
}
}
else if(gfd->Compressed==5) {
COLORREF color=0; BYTE* pColor = (BYTE*)&color;
for (ycount = 0; ycount < gfd->Height; ycount++) {
for (xcount = 0; xcount < gfd->Width; xcount++){
// ARRRRRBBBBBGGGGG
WORD pixel = *(WORD*)frame;
pColor[0] = ((pixel & 0x8000) == 0) ? 0 : 255;
pColor[1] = (pixel & 0x03E0) >> 2;
pColor[2] = (pixel & 0x001F) << 3;
pColor[3] = (pixel & 0x7C00) >> 7;
if( pColor[0] )
SetPixelV(hdc, xcount+xofs, ycount+yofs, color );
frame += 2;
}
}
}
else
for (ycount = 0; ycount < gfd->Height; ycount++)
for (xcount = 0; xcount < gfd->Width; xcount++)
SetPixelV(hdc, xcount+xofs, ycount+yofs, color[*frame++]);
}

void ShowFrameData(HWND hwndJpg, HDC hdc, VIEWOPTION *vo, TAFFRAMEDATA *gfd)
{
int i;
int *SubFrame;
TAFFRAMEDATA *gfdSub;

if( gfd->FramePointers==(-256) )
FrameToHDC(hdc, vo, gfd);
else if ( gfd->FramePointers ) {
SubFrame = (void *) (vo->buff + gfd->PtrFrameData);
for (i = 0; i < gfd->FramePointers; i++) {
gfdSub = (void *) (vo->buff + *SubFrame);
FrameToHDC(hdc, vo, gfdSub);
SubFrame++;
}
}
else
FrameToHDC(hdc, vo, gfd);
}

void SetCurrentFrame(HWND hwndJpg, VIEWOPTION *vo, int FrameNo)
{
char strFrameNo[16];
char strFramePtr[16];
TAFFRAMEDATA *gfd;
HWND hwnd = GetParent(hwndJpg);

vo->CurFrame = FrameNo;
sprintf( strFrameNo, "Frame %d", FrameNo );
//SetDlgItemInt(hwnd, IDC_CURFRAME, FrameNo, FALSE);
SetDlgItemText(hwnd, IDC_CURFRAME, strFrameNo );
gfd = vo->gfd[FrameNo];
SetDlgItemInt(hwnd, IDC_WIDTH, gfd->Width, TRUE);
SetDlgItemInt(hwnd, IDC_HEIGHT, gfd->Height, TRUE);
SetDlgItemInt(hwnd, IDC_XPOS, gfd->XPos, TRUE);
SetDlgItemInt(hwnd, IDC_YPOS, gfd->YPos, TRUE);
sprintf( strFramePtr, "%i", gfd->FramePointers );
SetDlgItemText(hwnd, IDC_SUBFRAMES, strFramePtr );
//SetDlgItemInt(hwnd, IDC_SUBFRAMES, gfd->FramePointers, FALSE);
SetDlgItemInt(hwnd, IDC_FRAME_UN, vo->FrameEntry[FrameNo].Unknown1, TRUE);
SetDlgItemInt(hwnd, IDC_FRAME_UN1, gfd->Unknown1, TRUE);
SetDlgItemInt(hwnd, IDC_FRAME_UN2, gfd->Unknown2, TRUE);
SetDlgItemInt(hwnd, IDC_FRAME_UN3, gfd->Unknown3, FALSE);
SetDlgItemInt(hwnd, IDC_FRAME_COMPRESSED, gfd->Compressed, TRUE);

InvalidateRect(hwndJpg, NULL, TRUE);
//UpdateWindow(hwndJpg);
}

void TafListSelect(HWND hwnd, HWND hwndList, VIEWOPTION *vo)
{
int index;
int i;
HWND hwndJpg = GetDlgItem(hwnd, IDC_PICTURE);

index = SendMessage(hwndList, LB_GETCURSEL, 0, 0);

if (index == LB_ERR)
return;

FreeFrameStuff(vo);

vo->CurEntry = (void *) SendMessage(hwndList, LB_GETITEMDATA, index, 0);
vo->FrameEntry = (void *) (vo->CurEntry+1);

SetDlgItemInt(hwnd, IDC_FRAMES, vo->CurEntry->Frames, FALSE);
SetDlgItemInt(hwnd, IDC_ENTRY_UN1, vo->CurEntry->Unknown1, FALSE);
SetDlgItemInt(hwnd, IDC_ENTRY_UN2, vo->CurEntry->Unknown2, FALSE);

SendDlgItemMessage(hwnd, IDC_SLIDE, TBM_SETRANGE, TRUE, MAKELONG(0, vo->CurEntry->Frames - 1));
SendDlgItemMessage(hwnd, IDC_SLIDE, TBM_SETPOS, TRUE, 0);

SetDlgItemText(hwnd, IDC_CURFRAME, "");
SetDlgItemText(hwnd, IDC_WIDTH, "");
SetDlgItemText(hwnd, IDC_HEIGHT, "");
SetDlgItemText(hwnd, IDC_XPOS, "");
SetDlgItemText(hwnd, IDC_YPOS, "");
SetDlgItemText(hwnd, IDC_SUBFRAMES, "");

if (!vo->CurEntry->Frames) {
InvalidateRect(hwndJpg, NULL, TRUE);
return;
}

vo->gfd = GetMem(vo->CurEntry->Frames * sizeof(TAFFRAMEDATA *), TRUE);

for (i = 0; i < vo->CurEntry->Frames; i++) {
vo->gfd[i] = (void *) (vo->buff + vo->FrameEntry[i].PtrFrameTable);
}

SetCurrentFrame(hwndJpg, vo, 0);
}

int LoadViewTaf(HWND hwnd, VIEWOPTION *vo)
{
TAFHEADER *Taf;
long *EntryPtr;
int EntryNo;
int Index;
TAFENTRY *Entry;
HWND hwndList;

Taf = (void *) vo->buff;
vo->Header = Taf;

EntryPtr = (long *) (vo->buff + sizeof(TAFHEADER));

SendDlgItemMessage(hwnd, IDC_TAFLIST, LB_RESETCONTENT, 0, 0);

for (EntryNo = 0; EntryNo < Taf->Entries; EntryNo++) {
Entry = (TAFENTRY *) (vo->buff + *EntryPtr);
Index = SendDlgItemMessage(hwnd, IDC_TAFLIST, LB_ADDSTRING, 0, (LPARAM) Entry->Name);
SendDlgItemMessage(hwnd, IDC_TAFLIST, LB_SETITEMDATA, Index, (LPARAM) Entry);

EntryPtr++;
}
if (EntryNo) {
hwndList = GetDlgItem(hwnd, IDC_TAFLIST);
SendMessage(hwndList, LB_SETCURSEL, 0, 0);
TafListSelect(hwnd, hwndList, vo);
}

return TRUE;
}

long WndProcViewTafInit(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
//wm_initdialog
HICON hiSmall;
HICON hiLarge;
RECT rc;
int x;
int y;
int inset;

VIEWOPTION *vo = (void *) (lParam);

SetWindowLong(hwnd, GWL_USERDATA, (long) vo);

hiSmall = LoadImage(hThisInstance, MAKEINTRESOURCE(IDI_MAIN), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
hiLarge = LoadIcon(hThisInstance, MAKEINTRESOURCE(IDI_MAIN));

SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM) hiLarge);
SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM) hiSmall);

SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM) vo->Name);
SetDlgItemText(hwnd, IDC_TAFNAME, vo->Name);

GetWindowRect(GetDlgItem(hwnd, IDC_TAFLIST), &rc);
ConvertToClient(hwnd, &rc);
inset = rc.left;
x = rc.right + inset;

GetWindowRect(GetDlgItem(hwnd, IDC_YPOS), &rc);
ConvertToClient(hwnd, &rc);
y = rc.bottom + inset;

CreateWindowEx(WS_EX_CLIENTEDGE, ViewTafJpgWindowClass, "",
WS_CHILD | WS_VISIBLE,
x, y, 100, 100,
hwnd, (HMENU) IDC_PICTURE, hThisInstance, NULL);

if (!LoadViewTaf(hwnd, vo))
PostMessage(hwnd, WM_CLOSE, 0, 0);

SetDlgItemInt(hwnd, IDC_ENTRIES, vo->Header->Entries, FALSE);
SetDlgItemInt(hwnd, IDC_HEADER_UN, vo->Header->Unknown1, TRUE);

return 0;
}

long WndProcViewTafSize(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
// wm_size
{
RECT rc;
HWND hwndChild;
int fwSizeType = wParam; // resizing flag
int nWidth = LOWORD(lParam); // width of client area
int nHeight = HIWORD(lParam); // height of client area
int x;

if (fwSizeType == SIZE_MINIMIZED)
return FALSE;

hwndChild = GetDlgItem(hwnd, IDC_TAFLIST);
GetWindowRect(hwndChild, &rc);
MoveWindow(hwndChild, 2, 2, rc.right-rc.left, nHeight - 4, TRUE);
x = rc.right - rc.left + 6;
hwndChild = GetDlgItem(hwnd, IDC_PICTURE);
GetWindowRect(hwndChild, &rc);
ConvertToClient(hwnd, &rc);
MoveWindow(hwndChild, x, rc.top, nWidth - x - 2, nHeight-rc.top-2, TRUE);
return FALSE;
}

LRESULT WndProcViewTafCommand(HWND hwnd, UINT message, WPARAM wParam, LONG lParam)
{
VIEWOPTION *vo;
UINT idItem = LOWORD(wParam);
UINT wNotifyCode = HIWORD(wParam);
HWND hwndCtl = (HWND) lParam;

vo = (void *) GetWindowLong(hwnd, GWL_USERDATA);

switch (idItem) {
case IDC_TAFLIST :
if (wNotifyCode == LBN_SELCHANGE)
TafListSelect(hwnd, hwndCtl, vo);
return 0;
}
return 0;
}

long WndProcViewTafScroll(HWND hwnd, UINT message, UINT wParam, LONG lParam)
{
// wm_hscroll - from slider
int wNotifyCode = LOWORD(wParam); // scroll bar value
VIEWOPTION *vo;
int NewPos;

vo = (void *) GetWindowLong(hwnd, GWL_USERDATA);

if (!vo->CurEntry->Frames)
return 0;

NewPos = SendMessage((HWND) lParam, TBM_GETPOS, 0, 0);
SetCurrentFrame(GetDlgItem(hwnd, IDC_PICTURE), vo, NewPos);
return 0;
}

long WndProcViewTafClose(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
VIEWOPTION *vo;
vo = (void *) GetWindowLong(hwnd, GWL_USERDATA);

FreeFrameStuff(vo);
if (vo->Name)
FreeMem(vo->Name);
if (vo->hpal)
DeleteObject(vo->hpal);
if (vo->buff)
FreeMem(vo->buff);
FreeMem(vo);

DestroyWindow(hwnd);
return FALSE;
}

LRESULT CALLBACK WndProcViewTaf(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) {
case WM_COMMAND :
return WndProcViewTafCommand(hwnd, message, wParam, lParam);
case WM_SIZE :
return WndProcViewTafSize(hwnd, message, wParam, lParam);
case WM_HSCROLL :
return WndProcViewTafScroll(hwnd, message, wParam, lParam);
case WM_INITDIALOG :
return WndProcViewTafInit(hwnd, message, wParam, lParam);
case WM_CLOSE :
return WndProcViewTafClose(hwnd, message, wParam, lParam);
}
return FALSE;
}

long WndProcViewJpgTafPaint(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
// wm_paint
{
PAINTSTRUCT ps;
VIEWOPTION *vo;
TAFFRAMEDATA *gfd;
RECT rc;
HWND hwndParent = GetParent(hwnd);

BeginPaint(hwnd, &ps);

vo = (void *) GetWindowLong(hwndParent, GWL_USERDATA);
if (vo->gfd) {
// Select palette and realize it.
SelectPalette(ps.hdc, vo->hpal, FALSE );
RealizePalette(ps.hdc);

gfd = (void *) (vo->buff + vo->FrameEntry[vo->CurFrame].PtrFrameTable);
GetClientRect(hwnd, &rc);

vo->xofs = (rc.right / 2) + vo->gfd[0]->XPos - (vo->gfd[0]->Width / 2);
vo->yofs = (rc.bottom / 2) + vo->gfd[0]->YPos - (vo->gfd[0]->Height / 2);

ShowFrameData(hwnd, ps.hdc, vo, gfd);
}
EndPaint(hwnd, &ps);
return 0;
}

LRESULT CALLBACK WndProcViewTafJpg(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) {
case WM_PAINT :
return WndProcViewJpgTafPaint(hwnd, message, wParam, lParam);
}
return DefWindowProc(hwnd, message, wParam, lParam);
}

void RegisterViewTafClasses(void)
{
WNDCLASSEX wndclass;

if (ViewTafClassRegistered)
return;

//Main Window
wndclass.cbSize = sizeof(wndclass);
wndclass.style = CS_HREDRAW | CS_VREDRAW; //CS_OWNDC;
wndclass.lpfnWndProc = WndProcViewTafJpg;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hThisInstance;
wndclass.hIcon = NULL;
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = ViewTafJpgWindowClass;
wndclass.hIconSm = NULL;
RegisterClassEx(&wndclass);

ViewTafClassRegistered = TRUE;
}

void DumpFrameData(FILE *f, char *buff, int PtrFrameTable, int FrameNo, int level)
{
TAFFRAMEDATA *gfd;
int *SubFrame;
int i;
char spaces[100];
int bytes;
char *data;
int count;
int mask;
int x;
int repeat;

FillMemory(spaces, sizeof(spaces), ' ');
spaces[level * 3] = 0;
gfd = (void *) (buff + PtrFrameTable);
fprintf(f, "%sW: %d H: %d X: %d Y: %d\n", spaces, gfd->Width, gfd->Height, gfd->XPos, gfd->YPos);
fprintf(f, "%sU1: %d Compressed: %d FramePointers: %d U2: %d U3: 0x%08X\n",
spaces, gfd->Unknown1, gfd->Compressed, gfd->FramePointers, gfd->Unknown2, gfd->Unknown3);
fprintf(f, "%sPtrFrameData: 0x%08X\n", spaces, gfd->PtrFrameData);
if (gfd->FramePointers) {
SubFrame = (void *) (buff + gfd->PtrFrameData);
for (i = 0; i < gfd->FramePointers; i++) {
DumpFrameData(f, buff, *SubFrame, i, level+1);
SubFrame++;
}
}
else {
data = buff + gfd->PtrFrameData;
for (i = 0; i < gfd->Height; i++) {
fprintf(f, "%sLine %3d", spaces, i);
bytes = *((short *) data);
data += sizeof(short);
count = 0;
while (count < bytes) {
mask = (unsigned char) data[count++];
if ((mask & 0x01) == 0x01) {
// transparent
for (x = 0; x < (mask >> 1); x++)
fprintf(f, " ");
}
else if ((mask & 0x02) == 0x02) {
// repeat next byte
repeat = (mask >> 2) + 1;
while (repeat--)
fprintf(f, " %02X", (unsigned char) data[count]);
count++;
}
else {
repeat = (mask >> 2) + 1;
while (repeat--)
fprintf(f, " %02X", (unsigned char) data[count++]);
}
}
data += bytes;
fprintf(f, "*\n");
}
fprintf(f, "\n");
data = buff + gfd->PtrFrameData;
for (i = 0; i < gfd->Height; i++) {
fprintf(f, "%sLine %3d", spaces, i);
bytes = *((short *) data);
data += sizeof(short);
for (count = 0; count < bytes; count++) {
fprintf(f, " %02X", (unsigned char) data[count]);
}
fprintf(f, "\n");
data += bytes;
}
}
}

void DumpTAF(char *buff, char *Name)
{
FILE *f;
char fname[MAX_PATH];
TAFHEADER *Taf;
long *EntryPtr;
int EntryNo;
TAFENTRY *Entry;
TAFFRAMEENTRY *FrameEntry;
int i;

strcpy(fname, Name);
strcat(fname, ".dmp");
f = fopen(fname, "wtc");


Taf = (void *) buff;

EntryPtr = (long *) (buff + sizeof(TAFHEADER));

for (EntryNo = 0; EntryNo < Taf->Entries; EntryNo++) {
Entry = (TAFENTRY *) (buff + *EntryPtr);
fprintf(f, "\nEntryPtr 0x%08X\nName %s Frames %d U1: %d U2: %d\n",
*EntryPtr, Entry->Name, Entry->Frames, Entry->Unknown1, Entry->Unknown2);
FrameEntry = (void *) (Entry+1);

if (Entry->Frames) {
for (i = 0; i < Entry->Frames; i++) {
fprintf(f, "Frame %d\n", i);
fprintf(f, "PtrFrameTable: 0x%08X\n", FrameEntry[i].PtrFrameTable);
fprintf(f, "FrameEntry.Unknown1: 0x%08X\n", FrameEntry[i].Unknown1);
DumpFrameData(f, buff, FrameEntry[i].PtrFrameTable, i, 0);
}
}
EntryPtr++;
}
fclose(f);
}

void InitVOStuff(VIEWOPTION *vo)
{
LOGPALETTE *lp;
PALETTEENTRY *pal;
int i;

// Allocate memory for color palette.
lp = GetMem(sizeof(LOGPALETTE)+(256 * sizeof(PALETTEENTRY)), FALSE);

lp->palVersion = 0x300;
lp->palNumEntries = 256;

// Load each color into the palette.
switch (vo->Version) {
case HPI_V1 :
pal = TAPalette;
break;
case HPI_V2 :
pal = TAKPalette;
break;
default :
pal = TAPalette;
}
for (i = 0; i < 256; i++ ) {
lp->palPalEntry[i].peRed = pal[i].peRed;
lp->palPalEntry[i].peGreen = pal[i].peGreen;
lp->palPalEntry[i].peBlue = pal[i].peBlue;
lp->palPalEntry[i].peFlags = pal[i].peFlags;
}

// Create the Palette.
vo->hpal = CreatePalette(lp);
FreeMem(lp);
}

int ViewTafFile(char *buff, int Length, char *Name, int option, HPIITEM *hi)
{
HWND hwnd;
VIEWOPTION *vo;

//DumpTAF(buff, Name);
//FreeMem(buff);
//return TRUE;

RegisterViewTafClasses();

vo = GetMem(sizeof(VIEWOPTION), TRUE);

vo->Version = hi->hfd->Version;
vo->Length = Length;
vo->buff = buff;
vo->Name = DupString(Name);
vo->option = option;

InitVOStuff(vo);

hwnd = CreateDialogParam(hThisInstance, MAKEINTRESOURCE(IDD_TAFVIEW),
NULL, WndProcViewTaf, (LPARAM) vo);

if (!hwnd)
return FALSE;

ShowWindow(hwnd, SW_SHOWNORMAL);

// buff is freed when the window closes
return TRUE;
}

Sorry if it long but hope you enjoy seeing what I see about TAF files.

Thanks guys.

_________________
" Boys have swag,
Men have style,
Gentlemen have class!"

-- Vaerun
Back to top Go down
View user profile
Wqaopl

avatar

Posts : 212
Reputation : 0
Join date : 2008-08-14

PostSubject: Re: Wqaopl's tnt maker   Wed Aug 10, 2016 5:51 pm

if you have the c++ code for the switch i would lie to see it and the other scripts such as "hpiview.h". and yes im kind of giving up on working out HIP myselth as i dont get much time to program =/

_________________
There are loads of modern ideas but new ideas are rare.
Back to top Go down
View user profile
$_Spagg

avatar

Posts : 387
Reputation : 16
Join date : 2010-10-31
Age : 104
Location : Brazil

PostSubject: Re: Wqaopl's tnt maker   Wed Aug 10, 2016 6:39 pm

hpiview.h and hpiview.c are in the hpiview source code I posted earlier

You can try their code, or wait until I make an hpi lib (which I should start since I pretty much gave up in continuing my kmap previewer as is) (Not that I gave up but that I want to rewrite it from scratch to avoid the spaggetti code that was created by loading the tnt, ota and txt files directly from the .kmp file (without properly organizing the headers etc)

If you try the hpiview source code just remember that it implements both TA hpi and TAK hpis and they are structurally different (hpiview source generally calls TA hpis by ____1 and TAK hpi things by ____2 like HPIENTRY1 and HPIENTRY2 structs or the LoadDirectory1 and LoadDirectory2 functions)
Also tak by default compresses with zlib while ta uses LZ77

If you run into a problem with an HPI related code you can post in this thread too
Back to top Go down
View user profile
Wqaopl

avatar

Posts : 212
Reputation : 0
Join date : 2008-08-14

PostSubject: Re: Wqaopl's tnt maker   Thu Aug 11, 2016 5:42 am

i atualy got round to unspegetiyfying my code

.h:
 

and

.cpp:
 

missing most of the bitmap setup and as i lirned c++ by my self theres no garenty of no mistakes but it should be easy to add to if needed =)

also i did not get round to adding palets for all the bitmaps

_________________
There are loads of modern ideas but new ideas are rare.
Back to top Go down
View user profile
$_Spagg

avatar

Posts : 387
Reputation : 16
Join date : 2010-10-31
Age : 104
Location : Brazil

PostSubject: Re: Wqaopl's tnt maker   Thu Aug 11, 2016 3:15 pm

Managing bitmaps for windows is so complicated I wish it was easy like with Qt images, this is how it is done in Qt:
Code:

QImage image = new QImage(wid, hei, QImage::Format_RGB32);
for (int y = 0; y < hei; y++) {
    for (int x = 0; x < wid; x++) {
        quint8 next = buffer->at(offset++);
        // QRgb pixel = qRgb(next, next, next); // greyscale color
        quint32 pixel = palette[next]; // palette color
        image->setPixel(x, y, pixel);
    }
}
Too bad I'll need to learn too if I want to finish thumbnail previewer for windows (even worse because i never programmed on Windows)

Anyway this is what I was talking about the features map, this is a rendered "tab" map:
(440 x 431)
Spoiler:
 

This is the rendered features map:
(320 x 320)
Spoiler:
 

Since the dimensions are different, the way I did to translate the mana coordinates was simple scaling math: newX = oldX * (newWid / oldWid)
Where oldX = the X coord in the features map; oldWid = the width of the featues map (320); newWid = the width of the tab map (440)
And the same for Y

Result:
Red circles = the mana on the resulting coordinates
Spoiler:
 

They might look to be aligned but they aren't, actually that is actualy in vain because the problem is that the features map doesn't scale correctly with the tab map, obviously.
Here's a justaposition of both (features map is scaled up):
Spoiler:
 

The misalignment becomes more visible the closes to the bottom right (higher coordinates)
Spoiler:
 

I believe Knowing how to fix this would also help with the cartographer since it is basically the same issue with dimension scaling that I mentioned earlier

A solution off my head is that to properly scaling the dimensions from the features map into the tab map dimensions first it's needed to crop the tab map (like cartographer seems to display a red area, that might be the area to crop) and then scale normally into the new cropped dimensions
Or maybe, instead of cropping the tab map it should be padded instead (to meet the same proportion as the featue maps, e.g 1:1 proportions)
Edit: padding the tab map dimensions clearly make much more sense since cropping would only make them more misaligned, now what is left is find out the proper ammount to pad the dimensions
I'll do some experimenting, if you have any idea please fire it off
Back to top Go down
View user profile
$_Spagg

avatar

Posts : 387
Reputation : 16
Join date : 2010-10-31
Age : 104
Location : Brazil

PostSubject: Re: Wqaopl's tnt maker   Thu Aug 11, 2016 3:35 pm

This is the red area in cartographer which I speak of and which the tab map cuts off causing the disproportionate dimensions:

(Measuring the pixels on the screen, seems to be always 16 for width and 64 for height)

Edit: this is even weirder than I thought
A 10 x 10  (cartographer settings) map gives me a 440 x 431 pixels tab map, but
a 8 x 8 map gives me a 442 x 431 pixels tab map
Even though the proportions are the same, the proportions for the tab map it creates isn't

Edit: Created some throwaway maps and now I saw a pattern here:
(cartographer sizes -> tab map sizes)
10 x 10 -> 440 x 431
9  x  9 -> 441 x 431
8  x  8 -> 442 x 431
7  x  7 -> 443 x 431
but then it becomes dumb out of a sudden
6  x  6 -> 446 x 431
5  x  5 -> 449 x 431
4  x  4 -> 453 x 431
3  x  3 -> 461 x 431
2  x  2 -> 478 x 431
1  x  1 -> 511 x 409
Back to top Go down
View user profile
Wqaopl

avatar

Posts : 212
Reputation : 0
Join date : 2008-08-14

PostSubject: Re: Wqaopl's tnt maker   Fri Aug 12, 2016 4:47 am

using the tab map or mini map is wong as they are scaled after the map is compiled for gameplay the mini map will alwayes fit into the top right box for egsample. use the height map for this and see if you get the same error.

as for bitmaps for windows i just go for a good egsample and ran with it the basic setup that is

unsigned char* pixels;
long imige_exsess = 0;

int bitwidth = FileHedder.Width;
while (bitwidth % 4 != 0)
{
bitwidth++;
imige_exsess++;
}

long pixwidth = FileHedder.Width;
long pixhight = FileHedder.Height;

HDC hdc = CreateCompatibleDC(NULL);
pbmi = (BITMAPINFO*)alloca(sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256);

pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
pbmi->bmiHeader.biWidth = bitwidth;
pbmi->bmiHeader.biHeight = -pixhight;
pbmi->bmiHeader.biPlanes = 1;
pbmi->bmiHeader.biBitCount = 8;
pbmi->bmiHeader.biCompression = BI_RGB;
pbmi->bmiHeader.biSizeImage = 0;// ((((pbmi->bmiHeader.biWidth * pbmi->bmiHeader.biBitCount) + 31) & ~31) >> 3) * pbmi->bmiHeader.biHeight;
pbmi->bmiHeader.biXPelsPerMeter = 14173;
pbmi->bmiHeader.biYPelsPerMeter = 14173;
pbmi->bmiHeader.biClrUsed = 0;
pbmi->bmiHeader.biClrImportant = 0;

long long arrlenth = bitwidth * pixhight;

for (int i = 0; i < 256; i++)
{
pbmi->bmiColors[i].rgbRed = i;
pbmi->bmiColors[i].rgbGreen = i;
pbmi->bmiColors[i].rgbBlue = i;
pbmi->bmiColors[i].rgbReserved = 0;
}

ACTIVEBITMAP = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)(&pixels), NULL, NULL);



CreateDIBSection is the funtion that does the magic and that bitmaps are always aliened to the forth byte. unsigned char* pixels is just a referance and is used by CreateDIBSection to return the bitmap array of pixels that you can alter anyway you want after.

the actural bitmap is in the HBITMAP but to use any inage you need to conect it to a DC and then use the DC such as StretchBlt to resize it to a thumnal size.

_________________
There are loads of modern ideas but new ideas are rare.
Back to top Go down
View user profile
$_Spagg

avatar

Posts : 387
Reputation : 16
Join date : 2010-10-31
Age : 104
Location : Brazil

PostSubject: Re: Wqaopl's tnt maker   Fri Aug 12, 2016 8:37 am

Yes but because the heightmap has the same dimensions as the features map so no scaling is needed
I'm very convinced that in order to scale first I need to add to the dimensions of the tab map the "cut" parts that appear on cartographer (those red parts don't get into the tab map, so they need to be added during the calculation to translate the features into the tab map) the only problem is find out the weird formula that generates 511x409 from 1x1 and 440x431 from 10x10
But if all goes wrong I'll have to put these in the height map afterall

and same for the player positions
Also thanks for the code with the bitmap
Back to top Go down
View user profile
Wqaopl

avatar

Posts : 212
Reputation : 0
Join date : 2008-08-14

PostSubject: Re: Wqaopl's tnt maker   Fri Aug 12, 2016 9:10 am

if you are loading the hpi files you could always just make a map image from the original bitmaps then scale \"***\" needed.

or subtract the offset from the feture map then scale it...

the famula for the size should not be hard to calculate i will give it a go

_________________
There are loads of modern ideas but new ideas are rare.
Back to top Go down
View user profile
$_Spagg

avatar

Posts : 387
Reputation : 16
Join date : 2010-10-31
Age : 104
Location : Brazil

PostSubject: Re: Wqaopl's tnt maker   Fri Aug 12, 2016 9:24 am

Yes Im loading directly from the hpi but what do you mean make a map image from the original bitmaps?
You mean create my own "tab" map by hand instead of using the one inside the tnt?
Back to top Go down
View user profile
Sponsored content




PostSubject: Re: Wqaopl's tnt maker   

Back to top Go down
 
Wqaopl's tnt maker
View previous topic View next topic Back to top 
Page 1 of 2Go to page : 1, 2  Next
 Similar topics
-
» Siggy Maker Shop!!!
» Kitten Or Puppy Maker Shop(OPEN)
» Tech Editor/Maker
» ? Game Maker Tutorials ?
» Super Mario Maker

Permissions in this forum:You cannot reply to topics in this forum
TA: Kingdoms Community Forum :: GENERAL :: General Chat-
Jump to: