코기 신작은 사쿠라혁명 마냥 장르물에 있어 치명적인 문제를 내포하고 시작하는지라 굳이 언급을 할 필요가 없을 것 같고 하고 있는 게임은 어쩌다보니 죄다 손이 크게 안가는데다 쉬어가는 시간 중인지라 하던거나 마저하고 있습니다.
글 주제와 상관없는 이야기지만 로사 리유니버스는 성석 안캐고 메인퀘에서 루즈퀘하는 분들이 보이는게 좀 밟히기는 하는데 누가 보는 것도 아니고 적어야 되나 좀 고민되긴하네요. 뭐 겜도 안하고 적으면 양심에 찔리니 해보고 슈로대DD나 적어야지.
nwnexplorer를 흉내내는 커맨드 라인용 프로그램의 목적은 앞서 말한대로 DLG 파일을 수정하기 위해서인데요.
1. 일단 첫번째 목적인 nwnexplorer의 경우 출력해주는 문자열 길이가 부족한 점을 해결했습니다. 고사양 시대 만세랄까?

2. nwnexplorer에서 출력해주지 않는 var data의 오프셋 값도 한 눈에 파악할 수 있도록 추가.
3. 그리고 16778216같은 커스텀tlk 관련 값의 경우 nwnexplorer에서 해당 변수 자료형 선언에 문제가 있는지 프로그램이 바로 튕깁니다. 그러니까 커스텀 tlk 파일과 dlg 파일을 연동하기 시작하면 nwnexplorer는 쓸 수가 없죠. 이 부분도 해결.
#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, *OUT;
char in_name[255];
char out_name[255];
char fix_name[255];
char *fix_buffer;
char *next_access = NULL;
int ck1 = 0;
uint32_t i;
uint32_t j;
strcpy_s(in_name, argv[1]);
strcpy_s(fix_name, in_name);
fix_buffer = strtok_s(fix_name, ".", &next_access);
strcpy_s(out_name, fix_buffer);
strcat_s(out_name, sizeof(out_name), ".test.dlg");
fopen_s(&IN1, in_name, "rb");
fopen_s(&OUT, out_name, "wb");
//Header
fread(&head1, sizeof(head1), 1, IN1);
if (!feof(IN1))
{
fwrite(&head1, sizeof(head1), 1, OUT);
//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);
if (!feof(IN1))
{
fwrite(entity1[i], sizeof(struct Entity), 1, OUT);
}
}
//Element
for (i = 0; i < head1.element_number; i++)
{
element1[i] = (Element*)malloc(sizeof(struct Element));
fread(element1[i], sizeof(struct Element), 1, IN1);
if (!feof(IN1))
{
fwrite(element1[i], sizeof(struct Element), 1, OUT);
}
}
//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);
if (!feof(IN1))
{
fwrite(varname1[i], sizeof(struct Varname), 1, OUT);
}
}
//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);
if (!feof(IN1))
{
fwrite(vardata1[i], sizeof(struct Vardata), 1, OUT);
}
}
//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);
if (!feof(IN1))
{
fwrite(multimap1[i], sizeof(struct Multimap), 1, OUT);
}
}
//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);
if (!feof(IN1))
{
fwrite(list1[i], sizeof(struct List), 1, OUT);
}
}
fclose(IN1); fclose(OUT);
//Test print
//Entry
for (i = 0; i < head1.entity_number; i++)
{
//test code
printf("Entry[%d] = (", i);
printf("%d,", entity1[i]->Code);
printf("%d,", entity1[i]->Index);
printf("%d)\n", entity1[i]->Number);
}
//test code
printf("\n");
//Element
for (i = 0; i < head1.element_number; i++)
{
//test code
printf("Element[%d] = (", i);
printf("%d, ", element1[i]->Type);
//printf("%d:", element1[i]->NameIndex);
printf("%s, ", varname1[element1[i]->NameIndex]->Name);
printf("%d", element1[i]->Offset);
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++;
//test code
printf(":");
for (j = 0; j < offset2; j++)
{
string1[i]->text[j] = vardata1[j + offset1]->Data;
}
string1[i]->text[j] = 0;
printf("%s", string1[i]->text);
}
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;
//test code
printf(":");
for (j = 0; j < offset2; j++)
{
//test code
//printf("%02x ", vardata1[j + offset1]->Data);
//printf("%c ", vardata1[j + offset1]->Data);
string1[i]->text[j] = vardata1[j + offset1]->Data;
}
string1[i]->text[j] = 0;
//test code
printf("%d/", string1[i]->Offset);
printf("%d/", string1[i]->tlk_ID);
printf("%d, ", string1[i]->tlk_Lang);
printf("%s", string1[i]->text);
}
if (element1[i]->Type == 15)
{
uint32_t offset1 = element1[i]->Offset / 4;
printf("->%d",offset1);
}
//test code
printf(")\n");
}
//test code
printf("\n");
//Var Name
for (i = 0; i < head1.varname_number; i++)
{
//test code
printf("VarName[%d] = (", i);
printf("%s)\n", varname1[i]->Name);
}
//test code
printf("\nVarData = ");
//Var Data
for (i = 0; i < head1.vardata_number; i++)
{
//test code
if (i % 16 == 0) printf("\n");
printf("%02x ", vardata1[i]->Data);
}
//test code
printf("\n\n");
//Multi Map
for (i = 0; i < head1.multimap_number / 4; i++)
{
//test code
printf("MultiMap[%d] = ", i);
printf("%d\n", multimap1[i]->Number);
}
//test code
printf("\n");
//List
for (i = 0; i < head1.list_number / 4; i++)
{
//test code
printf("List[%d] = ", i);
printf("%d\n", list1[i]->Number);
}
return 0;
}





덧글