Python has “batteries included” and as we all know Django is written in this language. Python has struct module (http://docs.python.org/lib/module-struct.html) which can do many interesting things.
If you played in Baldurs Gate, Icewind Dale or Planescape Torment then this mini tutorial may be quite interesting for you – we will read data from a binary file – Baldurs Gate II CHR file containing data abut players character. Before we continue check out:
pocketplane.net forums – How to read data from infinity engine files
IE File Formats list – specification of Infinity Engine files, we will use CHR v2
Requirements: you need a working django, can be development server. We will create one view and one template.
A example CHR file is attached to this page - look at the bottom.
- Create a view and hook it up in the urls.py:
from django.shortcuts import render_to_response import struct def view_char(request): file = open('media/Mag.chr', 'rb') try: text = file.read() finally: file.close() print text[0x0000:0x0000+4] print text[0x0004:0x0004+4] print text[0x0008:0x0008+32] return render_to_response('char.html')
Where ('media/Mag.chr') is a path to the CHR file. Create char.html template with some pointless text and open the view in the browser. In the terminal where the development server is running you should see something like this:
CHR V2.0 Daria
We have just read the basic data, and reading more isn't any problem (only problem is to specify the locations). Looking at CHR V2 and CRE V1 specification we can read more data:
from django.shortcuts import render_to_response import struct def view_char(request): file = open('media/Mag.chr', 'rb') try: text = file.read() finally: file.close() char = {} if str(text[0x0000:0x0000+4]) == 'CHR ': char['name'] = str(text[0x0008:0x0008+32]) a = struct.unpack('i', text[0x0028:0x0028+4]) # offset to CRE "file" a = 0x0000+a[0] if str(text[a:a+4]) == 'CRE ' and str(text[a+4:a+8]) == 'V1.0': char['xp'] = str(struct.unpack('i', text[a+0x0018:a+0x0018+4])[0]) char['hp'] = str(struct.unpack('h', text[a+0x0024:a+0x0024+2])[0]) char['pic'] = str(text[a+0x0034:a+0x0034+8]) char['str'] = str(struct.unpack('b', text[a+0x0238:a+0x0238+1])[0]) #str char['int'] = str(struct.unpack('b', text[a+0x023a:a+0x023a+1])[0]) #int char['wis'] = str(struct.unpack('b', text[a+0x023b:a+0x023b+1])[0]) #wis char['dex'] = str(struct.unpack('b', text[a+0x023c:a+0x023c+1])[0]) #dex char['con'] = str(struct.unpack('b', text[a+0x023d:a+0x023d+1])[0]) #con char['char'] = str(struct.unpack('b', text[a+0x023e:a+0x023e+1])[0]) #char # better error checking/reporting would be nice return render_to_response('char.html', {'char': char})
And the template:
<h1>{{ char.name }}</h1> <b>Hit Points</b>: {{ char.hp }}<br> <b>Experience Points</b>: {{ char.xp }}<br> <b>Strenght</b>: {{ char.str }}<br> <b>Dexterity</b>: {{ char.dex }}<br> <b>Constitution</b>: {{ char.con }}<br> <b>Inteligence</b>: {{ char.int }}<br> <b>Wisdom</b>: {{ char.wis }}<br> <b>Charisma</b>: {{ char.char }}
The results:
You can read and write to any binary file with python – you just need the specification which shows where the data is located and what type it is :) Note that there aren't available specifications for most proprietary file formats.
Attachments (1)
-
TBWojown.chr
(2.4 KB
) - added by 18 years ago.
Example CHR file
Download all attachments as: .zip