|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
That means for Room 1 that there are 2 pictures (picture A and picture B). Display A if the cypress tree (object No. 5) is present (= default picture), display B if the hollow stump (object No. 4) is present, instead. Simple, isn't it? To put this information into the logic hunk, the following codes are used: Condition codes (CC):
Display codes (DC):
That results in this byte order for our example room 1:
The sample source to get the logic information:
count = fgetc(gfx_in_file)*256
+ fgetc(gfx_in_file); // how many BYTES
// for room logic
fread(&in_dat[0],1,count,gfx_in_file);
while (j<count) {
rnum = in_dat[j++]; // room number
rp[rnum].ppr = in_dat[j++]; // number of cond. pics for room
for (i=0; i<rp[rnum].ppr; i++) {
rp[rnum].what[i] = in_dat[j++]; // display code
kk = rp[rnum].what[i]-80;
while (kk < 0) kk += 10;
for (k=0; k<kk; k++) {
rp[rnum].loc[i][k] = in_dat[j++]; // condition code
rp[rnum].obj[i][k] = in_dat[j++]; // object
}
rp[rnum].pnr[i] = in_dat[j++]; // picture number to display
// if condition is TRUE
}
}
And here's the source fragment to evaluate the complete logic info:
if (rp[Room].ppr) {
for (j=0; j<rp[Room].ppr; j++) {
ii = rp[Room].what[j]-80;
while (ii < 0) ii += 10;
yes = 0;
for (i=0; i<ii; i++) {
switch (rp[Room].loc[j][i]) {
case 1: // in room
if (Items[rp[Room].obj[j][i]].Location == MyLoc) yes++;
break;
case 2: // in inventory
if (Items[rp[Room].obj[j][i]].Location == 255) yes++;
break;
case 4: // in room or inventory
if ((Items[rp[Room].obj[j][i]].Location == 255) ||
(Items[rp[Room].obj[j][i]].Location == MyLoc)) yes++;
break;
case 81: // NOT in room
if (Items[rp[Room].obj[j][i]].Location != MyLoc) yes++;
break;
case 82: // NOT in inventory
if (Items[rp[Room].obj[j][i]].Location != 255) yes++;
break;
case 84: // NOT in room and NOT in inventory
if ((Items[rp[Room].obj[j][i]].Location != 255) &&
(Items[rp[Room].obj[j][i]].Location != MyLoc)) yes++;
break;
default:
break;
}
}
if (yes >= ii) {
if (rp[Room].pnr[j] == 0) { // no picture
if (pic_w_hdl) {
win_pos_ver = pic_w_hdl->LeftEdge; // save window position
win_pos_hor = pic_w_hdl->TopEdge;
CloseWindow(pic_w_hdl);
pic_w_hdl = 0;
}
last_pic = -128; // remember: no last pic
return(FALSE);
}
if (rp[Room].pnr[j] == 255) return(FALSE); // 255 = do nothing
if (last_pic >= 0) {
if ((go[last_pic] == go[rp[Room].pnr[j]])) return(FALSE);
}
switch ((int)(rp[Room].what[j]/10)) {
case PIC: // Show Pic
Open_Pic(rp[Room].pnr[j],PIC);
return(TRUE);
case COC: // colour cycling, not implemented yet
break;
case OVL: // overlay picture
yes = 1;
if (last_pic != Room) {
for (i=0; i<rp[Room].ppr; i++) {
if (last_pic == rp[Room].pnr[i]) {
yes = 0;
break;
}
}
}
else yes = 0;
if (yes) Open_Pic(Room,PIC); // basis pic is not already displayed
Open_Pic(rp[Room].pnr[j],OVL);
return(TRUE);
case ANI: // animation, not implemented yet
break;
case GOT: // GO_TREE for "Robin of Sherwood", not implemented yet
break;
default:
break;
}
}
}
}
Open_Pic(Room,PIC);
Data hunkFinally some picture data. 2 Formats are supported: Bitmaps and LineDrawPictures (LDP). BitmapsPictures are stored as chunky pixels, 6 bits per colour (bit 8 is the "repeat-flag" and bit 7 is the "overlay-flag"). Compressing is done via a slightly modified RLE algorithm (not very efficient at all but fast and most important, very easy to implement). One more word to bit 7 (overlay): If set, keep colour of default pic, else use colour from overlay pic. Use the source below for reading and decrompressing picture data:
fseek(gfx_in_file,go[pic_nr],SEEK_SET); // set position in file
NumColours = fgetc(gfx_in_file); // how many colours
for (i=0; i<NumColours; i++) { // fetch colours in RGB format
CR[i].red = fgetc(gfx_in_file);
CR[i].green = fgetc(gfx_in_file);
CR[i].blue = fgetc(gfx_in_file);
}
fread(&rle_dat[0],1,size,gfx_in_file); // get chunky data in rle_dat[]
j = i = 0; // and decompress it
while (j<size) { // into picture[]
while (rle_dat[j] < 128) {
picture[i++] = rle_dat[j++];
if (j>=size) return;
}
repeat = rle_dat[j++]-128;
for (count=0; count < repeat; count++) picture[i++] = rle_dat[j];
j++;
}
LDPPictures are stored as a sequence of drawing commands (MOVE, DRAW and FILL). Thus the picture size is very small compared to the the bitmap format.Overlay pictures are not supported. Use the source below for reading and drawing of picture data:
void Draw_Pic(UBYTE pic_nr, UBYTE mode)
{
UBYTE command,col;
UWORD x,y;
Check_Win();
if (pic_w_hdl) {
if (mode) {
if ((fgetc(gfx_in_file) != NEWPIC) || (fgetc(gfx_in_file) != pic_nr)) {
GFX_Off();
EasyRequest(act_w_hdl,&NoGFX,NULL,"GFX datafile corrupt\nor\
wrong datafile (NEWPIC/COL).\nGFX will be switched off.");
if (pic_w_hdl) CloseWindow(pic_w_hdl);
pic_w_hdl = 0;
return;
}
col = fgetc(gfx_in_file);
SetPen(col); // set background color
RectFill(rastPort,border_width,bar_height,gfx_width-1+border_width,
gfx_height-1+bar_height);
col=(col==0)?7:0;
SetPen(col); // set drawing color
DrawPicFrame(); // draw frame as border for FILL
if (FASTCOLOURS) {
SafeSetOutlinePen(rastPort,col+4);
}
else {
SafeSetOutlinePen(rastPort,Pens[col]); // set bordercolor for FLOOD 0
}
command = fgetc(gfx_in_file);
while (command != NEWPIC) {
switch (command) {
case MOVE:
y = fgetc(gfx_in_file) + bar_height;
x = fgetc(gfx_in_file) + border_width;
Move(rastPort,x,y);
break;
case FILL:
col = fgetc(gfx_in_file);
y = fgetc(gfx_in_file) + bar_height;
x = fgetc(gfx_in_file) + border_width;
SetPen(col);
Flood(rastPort,0,x,y);
break;
default: //DRAW
x = fgetc(gfx_in_file) + border_width;
Draw(rastPort,x,command + bar_height);
break;
}
command = fgetc(gfx_in_file);
}
}
else { //it's dark out there
SetPen(0); //black
RectFill(rastPort,border_width,bar_height,gfx_width-1+border_width,
gfx_height-1+bar_height);
DrawPicFrame(); // just to be on the safe side
}
}
Action 89... or how to look at something. Sometimes there are special pictures for some very special objects in the game. Try to "look at dragon" in Adventureland as an example. These pictures are stored right behind the default room pictures in the data hunk (and that means on the other hand right before the conditional room pictures). ToolsAll of those bitmap gfx-files are created with the help of some converting tools on my Amiga 3000. Source code is available at request, but be aware that this stuff is very Amiga specific because of the extensive use of datatypes. However, the basics are to take (snapshot) those bitmap gfx picture for picture from one or more of the original adventures (PDD's part and loads of work). Then merge them together with the gfx-logic (after converting, compressing and formatting) into one huge file and that's it. Sounds quite easy, doesn't it? Additionally there is a little tool to create LDP gfx files (basically written by David Lodge who discovered the LDP format) out of *.sna files (Sinclair Spectrum snapshots). And yes, this proggy even exists for Windooze machines. ConclusionOh well, what a mess. If you still know what's going on, don't blame me. But if you ever need further assistance you can always contact me and I'll be glad to help you.
|