목표로 했던 TLK에디터용 txt 파일 생성과 DLG파일 직접 수정하는 프로그램을 완성해봤습니다.
ks_ar0601_intro.new.dlg가 제가 생성해낸 데이타, ks_ar0601_introgff.dlg는 제가 GFF에디터로 만든 데이타이고 ks_ar0601_intro.dlg는 대거포드의 원본 데이타입니다.
실행시킨 결과물을 비교해보면 gff로 직접 수정한거와 조금 차이가 있는데 게임상에서나 GFF에디터상에서 문제없이 읽는게 가능한 상황.
실행프로그램.exe "ks_ar0601_intro.dlg" "1000"으로 실행시켜 나온 ks_ar0601_intro.new.txt는 TLK에디터의 배치작업용 TXT파일로 결과는 아래와 같습니다. 순차적으로 DLG파일을 직접 수정하기 때문에 이제는 그냥 TLK파일용으로 인덱싱해도 문제가 없죠.
#// ks_ar0601_intro.dlg
1000 := You shake off slumber slowly, clearing the dim fog of sleep from your weary eyes. It is quiet...too quiet. The creak of the caravan wagon's heavy axles and the steady rumble of its wheels upon the Trade Way road are strangely absent.
1001 := After quickly rubbing the sleep from your tired eyes, you pause to consider the events of the past few days. In Waterdeep, a fat halfling merchant named Falias hired you to accompany his caravan on this routine journey south along the Trade Way road towards the town of Daggerford.
1002 := Accompanying you is your longtime friend and faithful companion, Talarenne. You don't know how many times you have saved each other's lives but this seasoned fighter with long flowing dark hair and a mischievous smile is your most trusted companion.
1003 := Quickly looking around the small caravan wagon, you notice that your friend Talarenne is not here. Instead, you spot the fat halfling merchant, Falias, wringing his sweaty hands nervously.
1004 := "Excuse me. I apologize for waking you so soon after you had retired, but I am afraid there will be a short delay to our journey. A tree is blocking the road ahead, no doubt brought down by one of the recent storms."
1005 := "Oh no, certainly not. Your friend Talarenne is waiting outside and hoped that you might join her for a while."
1006 := "That be most kind of you to offer, but I believe the guards have everything in hand. Your friend Talarenne is waiting outside, however, and she asked if you would join her."
1007 := "Ah, excellent. I will tell Talarenne to expect you once you have made your preparations. Now, if you will excuse me..."
1008 := Falias bows before turning on his heels and leaving you alone to gather your belongings.
1009 := 16778226
1010 := 16778227
1011 := 16778228
1012 := 16778229
1013 := And you wake me just for this?
1014 := Has something happened to Talarenne?
1015 := Perhaps I could help to clear the way?
1016 := You may go now.
1017 := Since I'm already awake, I might as well step outside.
1018 := Tell Talarenne I'll be right out.
1019 := 16778236
1020 := 16778237
일단 계속 부여잡고 있었던 DLG파일 상으로는 문제가 없다고 봅니다만 실제로 써먹을 수 있을지는 테스트 파일을 늘려가면서 확인할 수 밖에 없겠죠.
#include "iostream"
#include "stdio.h"
#include "stdlib.h"
#pragma pack(push, 1)
struct Header {
char dlg_signature[4];
char dlg_version[4];
uint32_t entity_table;
uint32_t entity_number;
uint32_t element_table;
uint32_t element_number;
uint32_t varname;
uint32_t varname_number;
uint32_t vardata;
uint32_t vardata_number;
uint32_t multimap;
uint32_t multimap_number;
uint32_t list;
uint32_t list_number;
};
struct Entity {
uint32_t Code;
uint32_t Index;
uint32_t Number;
};
struct Element {
uint32_t Type;
uint32_t NameIndex;
union
{
uint8_t ui8;
int8_t si8;
uint16_t ui16;
int16_t si16;
uint32_t ui32;
int32_t si32;
float flt;
uint32_t Offset;
};
};
struct Varname {
char Name[12];
uint32_t Offset;
};
struct Vardata {
unsigned char Data;
};
struct Multimap {
uint32_t Number;
};
struct List {
uint32_t Number;
};
struct String {
uint32_t Offset;
int32_t tlk_ID;
uint32_t tlk_Lang;
unsigned char text[4096];
};
#pragma pack(pop)
struct Header head1;
struct Entity* entity1[999];
struct Element* element1[9999];
struct Varname* varname1[99];
struct Vardata* vardata1[99999];
struct Multimap* multimap1[9999];
struct List* list1[9999];
struct String* string1[9999];
int main(int argc, char* argv[])
{
FILE* IN1, * OUT1, * OUT2;
char out_id[16];
char in_name[255];
char out_name1[255];
char out_name2[255];
char fix_name[255];
char* fix_buffer;
char* next_access = NULL;
int textlen1 = 0;
uint32_t tlk_id1 = 0;
uint32_t tlk_id2 = 0;
//uint32_t temp_offset = 0;
uint32_t i, j, k;
strcpy_s(in_name, argv[1]);
strcpy_s(out_id, argv[2]);
tlk_id1 = atoi(out_id);
tlk_id2 = atoi(out_id);
strcpy_s(fix_name, in_name);
fix_buffer = strtok_s(fix_name, ".", &next_access);
strcpy_s(out_name1, fix_buffer);
strcat_s(out_name1, sizeof(out_name1), ".new.txt");
strcpy_s(out_name2, fix_buffer);
strcat_s(out_name2, sizeof(out_name2), ".new.dlg");
//NWN Data read
fopen_s(&IN1, in_name, "rb");
//Header
fread(&head1, sizeof(head1), 1, IN1);
if (!feof(IN1))
{
//test code
printf("entity = (%d,", head1.entity_table);
printf("%d) ", head1.entity_number);
printf("element = (%d,", head1.element_table);
printf("%d) ", head1.element_number);
printf("varname = (%d,", head1.varname);
printf("%d)\n", head1.varname_number);
printf("vardata = (%d,", head1.vardata);
printf("%d) ", head1.vardata_number);
printf("multimap = (%d,", head1.multimap);
printf("%d) ", head1.multimap_number);
printf("list = (%d,", head1.list);
printf("%d)\n\n", head1.list_number);
}
//Entry
for (i = 0; i < head1.entity_number; i++)
{
entity1[i] = (Entity*)malloc(sizeof(struct Entity));
fread(entity1[i], sizeof(struct Entity), 1, IN1);
}
//Element
for (i = 0; i < head1.element_number; i++)
{
element1[i] = (Element*)malloc(sizeof(struct Element));
fread(element1[i], sizeof(struct Element), 1, IN1);
}
//Var Name
for (i = 0; i < head1.varname_number; i++)
{
varname1[i] = (Varname*)malloc(sizeof(struct Varname));
fread(varname1[i], sizeof(struct Varname), 1, IN1);
}
//Var Data
for (i = 0; i < head1.vardata_number; i++)
{
vardata1[i] = (Vardata*)malloc(sizeof(struct Vardata));
fread(vardata1[i], sizeof(struct Vardata), 1, IN1);
}
//Multi Map
for (i = 0; i < head1.multimap_number / 4; i++)
{
multimap1[i] = (Multimap*)malloc(sizeof(struct Multimap));
fread(multimap1[i], sizeof(struct Multimap), 1, IN1);
}
//List
for (i = 0; i < head1.list_number / 4; i++)
{
list1[i] = (List*)malloc(sizeof(struct List));;
fread(list1[i], sizeof(struct List), 1, IN1);
}
fclose(IN1);
//String in Var Data
for (i = 0; i < head1.element_number; i++)
{
if (element1[i]->Type == 10)
{
string1[i] = (String*)malloc(sizeof(struct String));
uint32_t offset1 = element1[i]->Offset;
for (j = 0; j < 4; j++)
{
string1[i]->Offset = string1[i]->Offset << 8;
string1[i]->Offset = string1[i]->Offset + vardata1[3 - j + offset1]->Data;
}
uint32_t offset2 = string1[i]->Offset;
offset1 = offset1 + 4;
for (j = 0; j < offset2; j++)
string1[i]->text[j] = vardata1[j + offset1]->Data;
string1[i]->text[j] = 0;
}
if (element1[i]->Type == 11)
{
string1[i] = (String*)malloc(sizeof(struct String));
uint32_t offset1 = element1[i]->Offset;
uint32_t offset2 = (uint32_t)vardata1[offset1]->Data;
offset1++;
for (j = 0; j < offset2; j++)
string1[i]->text[j] = vardata1[j + offset1]->Data;
string1[i]->text[j] = 0;
}
if (element1[i]->Type == 12)
{
string1[i] = (String*)malloc(sizeof(struct String));
uint32_t offset1 = element1[i]->Offset;
for (j = 0; j < 4; j++)
{
string1[i]->Offset = string1[i]->Offset << 8;
string1[i]->Offset = string1[i]->Offset + vardata1[3 - j + offset1]->Data;
string1[i]->tlk_ID = string1[i]->tlk_ID << 8;
string1[i]->tlk_ID = string1[i]->tlk_ID + vardata1[7 - j + offset1]->Data;
string1[i]->tlk_Lang = string1[i]->tlk_Lang << 8;
string1[i]->tlk_Lang = string1[i]->tlk_Lang + vardata1[11 - j + offset1]->Data;
}
uint32_t offset2 = string1[i]->Offset - 16;
offset1 = offset1 + 20;
//zero length
if (offset2 > 2147483647) offset2 = 0;
for (j = 0; j < offset2; j++)
string1[i]->text[j] = vardata1[j + offset1]->Data;
string1[i]->text[j] = 0;
}
}
//Search and print
fopen_s(&OUT1, out_name1, "w");
fputs("#// ", OUT1);
fputs(in_name, OUT1);
fputs("\n", OUT1);
for (i = 0; i < head1.element_number; i++)
{
if (element1[i]->Type == 12)
{
_itoa_s(tlk_id1, out_id, 10);
tlk_id1++;
textlen1 = strlen((const char*)string1[i]->text);
//textlen1 = string1[i]->Offset - 16;
//if (textlen1 < 0) textlen1 = 0;
fputs(out_id, OUT1);
fputs(" := ", OUT1);
fwrite(string1[i]->text, sizeof(char) * textlen1, 1, OUT1);
if (textlen1 == 0)
{
_itoa_s(tlk_id1 + 16777216, out_id, 10);
fputs(out_id, OUT1);
}
fputs("\n", OUT1);
}
}
fclose(OUT1);
//DLG edit
tlk_id2 = tlk_id2 + 16777216;
for (i = 0; i < head1.element_number; i++)
{
uint32_t offset1 = element1[i]->Offset;
if (element1[i]->Type == 12)
{
textlen1 = strlen((const char*)string1[i]->text);
if (textlen1 > 0)
{
uint32_t offset2 = string1[i]->Offset - 8;
//if (offset2 > 2147483647) offset2 = 0;
string1[i]->Offset = 8;
string1[i]->tlk_ID = tlk_id2;
unsigned char* tlk_offset_adress = (unsigned char*)&string1[i]->Offset;
unsigned char* tlk_ID_adress = (unsigned char*)&string1[i]->tlk_ID;
for (j = 0; j < 4; j++)
{
vardata1[j + offset1]->Data = *(tlk_offset_adress + j);
vardata1[4 + j + offset1]->Data = *(tlk_ID_adress + j);
vardata1[8 + j + offset1]->Data = 0; //Blank
}
uint32_t offset3 = head1.vardata_number - offset1 - offset2;
//char array shift
memmove(vardata1 + offset1 + 16, vardata1 + 16 + offset1 + offset2, sizeof(int)*offset3);
//Offset resize
head1.vardata_number = head1.vardata_number - offset2;
head1.multimap = head1.multimap - offset2;
head1.list = head1.list - offset2;
if (offset2 > 0)
{
for (k = i + 1; k < head1.element_number; k++)
{
if (element1[k]->Type == 10)
element1[k]->Offset = element1[k]->Offset - offset2;
if (element1[k]->Type == 11)
element1[k]->Offset = element1[k]->Offset - offset2;
if (element1[k]->Type == 12)
element1[k]->Offset = element1[k]->Offset - offset2;
}
}
}
tlk_id2++;
}
}
//DLG export
fopen_s(&OUT2, out_name2, "wb");
//test code start
printf("%s\n", out_name2);
printf("entity = (%d,", head1.entity_table);
printf("%d) ", head1.entity_number);
printf("element = (%d,", head1.element_table);
printf("%d) ", head1.element_number);
printf("varname = (%d,", head1.varname);
printf("%d)\n", head1.varname_number);
printf("vardata = (%d,", head1.vardata);
printf("%d) ", head1.vardata_number);
printf("multimap = (%d,", head1.multimap);
printf("%d) ", head1.multimap_number);
printf("list = (%d,", head1.list);
printf("%d)\n\n", head1.list_number);
//interval
/*for (i = 0; i < head1.element_number; i++)
{
if (element1[i]->Type == 10 || element1[i]->Type == 11 || element1[i]->Type == 12)
{
printf("Element[%d] = (", i);
printf("%d, ", element1[i]->Type);
printf("offset:%d,", element1[i]->Offset);
printf("interval:%d\n", (element1[i]->Offset - temp_offset));
temp_offset = element1[i]->Offset;
}
}*/
//test code end
fwrite(&head1, sizeof(head1), 1, OUT2);
for (i = 0; i < head1.entity_number; i++)
fwrite(entity1[i], sizeof(struct Entity), 1, OUT2);
for (i = 0; i < head1.element_number; i++)
fwrite(element1[i], sizeof(struct Element), 1, OUT2);
for (i = 0; i < head1.varname_number; i++)
fwrite(varname1[i], sizeof(struct Varname), 1, OUT2);
for (i = 0; i < head1.vardata_number; i++)
fwrite(vardata1[i], sizeof(struct Vardata), 1, OUT2);
for (i = 0; i < head1.multimap_number / 4; i++)
fwrite(multimap1[i], sizeof(struct Multimap), 1, OUT2);
for (i = 0; i < head1.list_number / 4; i++)
fwrite(list1[i], sizeof(struct List), 1, OUT2);
fclose(OUT2);
return 0;
}





덧글