Jump to content

BG2 Tweak Pack v16 Released


CamDawg

Recommended Posts

Most of the README links included with V16 appear to be broken, e.g. "Icewind Dale Casting Graphics" at http://forums.gibberlings3.net/index.php?app=gallery&album=27 returns to the main forum.

 

The link in the on-site README does lead to the right thread, but the images are broken. :(

 

I'ts been a while since my last play through, but the tweak pack (and whatever it becomes as it merges with other tools) has always been the first thing I install. Fine piece of software.

Link to comment

Guys, i'm not toally sure if this is the right place to ask this, but i cannot think of a better one.

 

I'm on Ubuntu 15, with GOG's version of BG2EE and bgw_tweaks v16.

Now, bgw_tweaks requires "tolower" util to be run before its installation. Or else "weinstall bg2_tweaks" fails (fails to find a proper language directory, and if i lowercase the directory names myself, it then fails to copy multiple files during mods installation).

 

However, "tolower" ruins the game - i cannot launch it after i "tolower" it.

The GOG's console util seem to be working fine, after i change "BaldursGateII" to "baldursgateii" in start.sh - but then it still fails to launch the game. A new window appears for a slight moment, only to be closed immediately.

 

What should i do?

Link to comment

However, "tolower" ruins the game - i cannot launch it after i "tolower" it.

The GOG's console util seem to be working fine, after i change "BaldursGateII" to "baldursgateii" in start.sh - but then it still fails to launch the game. A new window appears for a slight moment, only to be closed immediately.

BaldursGateII is the executable's name in the native linux Steam version. Is the GOG version also native (GOG usually gives wine prefixes that is why i ask) ?

 

Also have you lowercased with tolower all the files in the game folder (for example the bif files in the data/ folder) ?

 

I had the same problem with installing mods in the native linux version. BaldursGateII has some paths and filenames hardcoded in it and if it cannot open the file, you get a segmentation fault (probably the "window closes immediately" you experience).

 

1) One proposal in the gog forums is to run a shell script that runs tolower to lowercase the names but saves them in a file and after you install the mods, you can rename them to their proper case.

 

2) Another way is to use ciopfs. ciopfs is a pseudo filesystem that can be used to make a directory appear case insensitive like FAT/NTFS in windows. You can mount the game directory with ciopfs and then only access it through the new directory and everything will work perfectly. This is the easiest way.

 

3) I did something different. The steps i did to make the game work were the following:

 

a) BaldursGateII has en_US (or relevant language folder) hardcoded. So i could either open the executable with a hex editor and change the folder name to en_us or make a symbolic link. I liked the second way better so i opened a terminal and did

% cd /path/to/game/folder
% ln -snf en_us lang/en_US
% ls -al lang
drwxr-xr-x 1  58 Νοέ  24 18:43 de_de/
drwxr-xr-x 1  62 Νοέ  24 18:43 en_us/
lrwxrwxrwx 1   5 Δεκ  14 11:59 en_US -> en_us/
drwxr-xr-x 1  58 Νοέ  24 18:43 es_es/
As you see, there is a en_US "directory" that is the same as the en_us one. This way, the linux binary can access the directory and find dialog.tlk. The only "problem" with this way is that weidu reports 2 english languages which is a bit ugly but doesn't hurt anything.

 

b) Now there is another problem. The BIF files that will be accessed by the binary in order to find the game resources are stored in the chitin.key file. The file as it comes with BG2EE has mixed-case entries (e.g data/CREAnim.bif) and when you install some mod, weidu changes them to uppercase. The result is that the binary cannot access them. Based on IESDP, i wrote a c program that opens the chitin.key file and lowercases these entries without changing anything else.

 

 

#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <errno.h>
#include <string.h>
#include <sys/stat.h>
#include <ctype.h>

struct key_header {
	uint8_t sig[4];        /* 0x00: "KEY " */
	uint8_t ver[4];        /* 0x04: "V1  " */
	uint32_t bifcnt;       /* 0x08: Count of BIF entries */
	uint32_t rescnt;       /* 0x0c: Count of resource entries */
	uint32_t bifoff;       /* 0x10: Offest to BIF entries */
	uint32_t resoff;       /* 0x14: Offest to resource entries */
} __attribute__((packed));

struct bif_header {
	uint32_t biflen;       /* 0x00: Length of BIF file */
	uint32_t fileoff;      /* 0x04: Offset to ASCIIZ BIF filename */
	uint16_t filelen;      /* 0x08: Length of ASCIIZ BIF filename */
	uint16_t location;     /* 0x0a: Location of the file */
} __attribute__((packed));

struct res_header {
	uint8_t resname[8];    /* 0x00: Resource name */
	uint16_t restype;      /* 0x08: Resource type */
	uint32_t locator;      /* 0x0a: Resource locator */
} __attribute__((packed));

struct chitin {
	struct key_header header;
	struct bif_header *bif;
	struct res_header *res;
	char *name;
	size_t size;
};


struct chitin *init_chitin(void)
{

	struct chitin *chitin;

	chitin = calloc(1, sizeof *chitin);
	if (chitin == NULL) {
		errno = -ENOMEM;
		return NULL;
	}

	chitin->bif = NULL;
	chitin->res = NULL;
	chitin->name = NULL;

	return chitin;
}

void free_chitin(struct chitin *chitin)
{
	free(chitin->name);
	free(chitin->bif);
	free(chitin->res);
	free(chitin);
}

int read_key(const char *filename, struct chitin *chitin)
{
	FILE *f;
	struct stat st;
	int r;
	int i, j;
	int len;
	int off;
	char buf[512];

	errno = 0;

	if ((filename == NULL) || (chitin == NULL)) {
		errno = -EFAULT;
		goto out;
	}
	f = fopen(filename, "r+b");
	if (f == NULL) {
		errno = -ENOENT;
		goto out;
	}
	r = fstat(fileno(f), &st);
	if (r < 0) {
		errno = -ENOENT;
		goto fc;
	}

	r = fread(&chitin->header, sizeof chitin->header, 1, f);
	if (r < 1) {
		errno = -ENODATA;
		goto fc;
	}

	r = memcmp(chitin->header.sig, "KEY ", 4);
	if (r != 0) {
		errno = -EINVAL;
		goto fc;
	}
	r = memcmp(chitin->header.ver, "V1  ", 4);
	if (r != 0) {
		errno = -EINVAL;
		goto fc;
	}

	chitin->bif = calloc(chitin->header.bifcnt, sizeof *chitin->bif);
	if (chitin->bif == NULL) {
		errno = -ENOMEM;
		goto fc;
	}
	fseek(f, chitin->header.bifoff, SEEK_SET);
	r = fread(chitin->bif, sizeof *chitin->bif, chitin->header.bifcnt, f);
	if (r < chitin->header.bifcnt) {
		errno = -ENODATA;
		goto fc;
	}

	for (i = 0; i < chitin->header.bifcnt; i++) {
		off = chitin->bif[i].fileoff;
		len = chitin->bif[i].filelen;
		fseek(f, off, SEEK_SET);
		fread(buf, 1, len, f);
		for (j = 0; j < len - 1; j++) {
			if isupper(buf[j]) {
				buf[j] = tolower(buf[j]);
			}
		}
		fseek(f, off, SEEK_SET);
		fwrite(buf, 1, len, f);
	}

	fseek(f, chitin->header.resoff, SEEK_SET);
	chitin->res = calloc(chitin->header.rescnt, sizeof *chitin->res);
	if (chitin->res == NULL) {
		errno = -ENOMEM;
		goto fc;
	}
	r = fread(chitin->res, sizeof *chitin->res, chitin->header.rescnt, f);
	if (r < chitin->header.rescnt) {
		errno = -ENODATA;
		goto fc;
	}

	for (i = 0; i < chitin->header.rescnt; i++) {
		for (j = 0; j < 8; j++) {
			if (isupper(chitin->res[i].resname[j])) {
				chitin->res[i].resname[j] = tolower(chitin->res[i].resname[j]);
			}
		}
	}
	fseek(f, chitin->header.resoff, SEEK_SET);
	r = fwrite(chitin->res, sizeof *chitin->res, chitin->header.rescnt, f);

	chitin->name = strdup(filename);

fc:
	fclose(f);
out:
	return errno;
}

int main(int argc, char *argv[])
{
	int i, j;
	int r;
	struct chitin *chitin;
	
	if (argc != 2)
		return -1;

	chitin = init_chitin();

	read_key(argv[1], chitin);

	if (chitin) {
		printf("Processing chitin %s - %s\n", argv[1], chitin->name);
		printf("Found %d BIF entries\n", chitin->header.bifcnt);
		printf("Found %d resource entries\n", chitin->header.rescnt);
	}

	free_chitin(chitin);

	return 0;
}

 

You can compile this file and then run it with "chitin.key" as argument after each mod installation. If it doesn't make any difference in windows, maybe the next weidu can be modified to always produce lowercased entries in bif/key files.

 

With any of these ways, you can run the game fine. I recommend to install the ciopfs from your distribution's package manager and use that as it is the most straightforward way.

Link to comment

khelban12, you're a life saver :)

 

Thanks a lot for detailed explanations - yes, i get the segmentation fault, too, so your solutions seem to be the ones i need.

 

Think I'll try your own approach, as it seems to be the more sophisticated one.

 

Will let you know how it goes, in a couple of days, when i try it. :)

 

Thanks again!

Link to comment

I couldn't wait so spent about 20 minutes applying your "manual" approach.

 

And it worked like a charm!

 

Man, i love you. :D

I am glad i helped. Just have in mind that you will need to rerun the "lowercase" program i gave after every major mod installation.

 

The ciopfs method has the benefit that it has the least maintenance. You can tell the system to auto mount the directory on boot and then forget everything about it. You just access the game only through the "case insensitive" directory and everything automagically works.

Link to comment

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...