VOGONS


First post, by Binleroy

User metadata
Rank Newbie
Rank
Newbie

Hey i was wondering if anyone could help me with a problem i'm having.

I am using to host dosbox (q6600 win7 pro 64bit 😦 4gb mem 768mb 8800gtx) using dosbox 0.74

I went through all the trouble off getting betrayal in antarra to work for the win3.11 (game is 3cd's all iso) (had some old floppy's with win3.1) i have installed in dosbox. i installed video drivers (s3) and audio (sb16) (after finaly finding the one's that worked) set the cputype=486_slow so i got past the error code 21. installed the game in win 3.1 (game includes win32s) (share.exe starts before win does) (manualy mount my deamon tools mounted iso with mount d: f:\ or my drive's disapear in win3.11) (installed the game update also)

i added following to dosbox conf also under autoexec setting
mount c c:\doswin
c:
SET PATH=%PATH%;C:\WINDOWS;
SET TEMP=C:\WINDOWS\TEMP
ver set 6 22
LH c:\dos\share.exe

The Problem:

But now i can play the game just fine (sometimes i also get the error playing but not that often) but when i save a game and then try to load it i get ERROR: could not open database file! (TRW_FLAG.WDB) when i click ok the game gives a fatal error and shuts down.
I also seen 2 other ppl so far with this problem on another forum but those where years ago and never got solved. i would love to get this working somehow.

I have no clue how to get this one fixed i was thinking it could be permission related or something so gave it all full control but that dident help any. then i thought it could be becouse my host's hard drive is ntfs formatted but i'm not sure? dont rly feel like reinstalling my windows 7 to find out. maybe someone could help me out here..? 😢

Attachments

  • Filename
    Antara.jpg
    File size
    42.05 KiB
    Downloads
    138 downloads
    File comment
    I updated the pic with also an error i get trying to use the game's bookmark (quick save feuture)
    File license
    Fair use/fair dealing exception
Last edited by Binleroy on 2010-07-11, 00:20. Edited 1 time in total.

Reply 1 of 37, by paulacchang2

User metadata
Rank Newbie
Rank
Newbie

Yes, I encountered this problem also some years back, and never did solve it. Something to do with share.exe? I'm not that familiar with DOS and Windows, but if somebody has a general idea of what needs to be done to DOSBox (i.e. *minor* changes to the code) to fix this, I'd be happy to work on a fix ...

Reply 2 of 37, by Binleroy

User metadata
Rank Newbie
Rank
Newbie

I wonder if the game uses a specific win 3.11 program to open the wdb file that i might not have installed? (nothing about this in any readme of the game)

(the game does state it needs a 30MB permanent swap file to run i do have a swap file in win3.11 (to get there go to control pannel - 386 enhanced - virtual memory - change) but its a temporary 60mb one when i try to set it to permanent the maximum size is 0mb somehow i cant seem to change this i tired adding mount c: C:\doswin -freesize 1024 to dosbox conf to give it more hard disk space but that also left me with 0mb for permanent (the extra room appeared at temporary) i dont know if this could be a couse of the problem but i guess its worth a try getting a permanent one somehow??? if anyone knows how to do this plz let me know 😀

As far as the share.exe this seems to work just fine becouse if i dont load the share.exe the game wont run at all and give back an error code 21 trying to start it. I copied an installed ms dos to a folder inside my mounted C with share.exe in it so i think this should be working.

then the dosbox conf like i posted above
ver set 6 22
LH c:\dos\share.exe
then when i type share.exe it says its alrdy installed so share.exe is working i guess.

Last edited by Binleroy on 2010-07-10, 14:08. Edited 1 time in total.

Reply 3 of 37, by Qbix

User metadata
Rank DOSBox Author
Rank
DOSBox Author

share might be loaded, but it doesn't work.
we don't call the functions it installs, when opening or reading files.

Water flows down the stream
How to ask questions the smart way!

Reply 4 of 37, by Binleroy

User metadata
Rank Newbie
Rank
Newbie

i am not sure what you mean? dosbox doesen call the functions that share.exe installs when opening or reading files? what exactly is call the functions ? and how do u make dosbox do that 😜

Reply 5 of 37, by paulacchang2

User metadata
Rank Newbie
Rank
Newbie

But perhaps you could 'emulate' the file lock behaviour of share.exe (yet I understand this could be a lot of work)? Just return the expected return codes after the program calls a file-sharing function, like Lock/Unlock File (Int 21h function 5ch) for instance.

(Although this may or may not be dangerous with respect to corrupting file data, if this is not done carefully? That is, you actually have to implement the right thing, rather than just emitting the expected return codes? I don't know).

Reply 6 of 37, by Qbix

User metadata
Rank DOSBox Author
Rank
DOSBox Author

well returning the proper codes, is pretty simple, (of course no locking is done)
but we don't even know for sure that share is causing the problem...
It says unable to open a file...
You'd have to check with a debugger if that really happens and why that file can't be opened.
It might be a bug in a totally different system.

Water flows down the stream
How to ask questions the smart way!

Reply 7 of 37, by Binleroy

User metadata
Rank Newbie
Rank
Newbie

Hey i found something very interesting in the troubleshooting guide of the game.^^ so share.exe is indeed the problem here... i kept looking over this line somehow... so can seomeone help me fix it now 😜 please can you tell me how to do the return code thing or do it for me ? couse i am not that good at that stuff myself. i am also not sure how the debugger thing works. I tried compiling dosbox in visual c++ as a friend suggested to use for debugging but the output of that program dident make much sense to me. i did however find the following in the game's troubleshoot.

Problem: When I try to restore a saved game (in Windows 3.x) I receive an error "ERROR: Could not open database file! (TRW_FLAG.WDB)"
Solution: This error indicates that SHARE.EXE is not loaded. SHARE must be installed to play the game. To install SHARE.EXE, exit out of Windows 3.x and into MS-DOS. Then at the C:\ prompt, type "SHARE.EXE". This will load SHARE. You can then re-enter Windows and play the game as normal.

Attachments

  • Filename
    ANTARA.DOC
    File size
    134.06 KiB
    Downloads
    146 downloads
    File comment
    This is theTroubleshooting of the game where i found this in.^^
    File license
    Fair use/fair dealing exception

Reply 8 of 37, by Qbix

User metadata
Rank DOSBox Author
Rank
DOSBox Author

maybe use a image with msdos (imgmount, boot)
I might add share support oneday, but it is not very high on my priorities list. (this is the first game that needs it(that I can recall) and it isn't even a dos game)

Water flows down the stream
How to ask questions the smart way!

Reply 9 of 37, by paulacchang2

User metadata
Rank Newbie
Rank
Newbie

So I ran Antara and tried to load a save game, stepping thru DOSBox with a debugger, and it looks like the lock/unlock functions are never called, although all the calls to INT 21/3D are done with AL=40 or AL=42 (that is, all the AL's have been ORed with 40). I also hacked in an Interrupt 2F handler, to see if a share installation check was done (using INT 2F/AX=1000h) and it seems this check is not done either.

Too much work for too little gain. I'll suggest people just install and play Antara in a virtual machine, running Windows 95.

Reply 10 of 37, by Qbix

User metadata
Rank DOSBox Author
Rank
DOSBox Author

you might get it working by changing our fopen calls to shared versions of fopen.
they could be trying to open the same twice with different flags.
(or change the first call to a 42 so the file is opened in read write mode)

Water flows down the stream
How to ask questions the smart way!

Reply 11 of 37, by ripsaw8080

User metadata
Rank DOSBox Author
Rank
DOSBox Author

Betrayal in Antara relies on a behavior of SHARE.EXE that does not work with DOSBox's local drive mounts. When a file handle is opened, then written to such that the length of the file is increased, and then the file is opened again (the first handle is still open), the second handle does not see the updated length of the file unless SHARE.EXE is loaded (or the first handle is flushed).

Adding fflush() in drive_local.cpp following fwrite() prevents the issue, but it could cause problems for other games that expect different (i.e. not share-like) behavior:

 bool localFile::Write(Bit8u * data,Bit16u * size) {
if ((this->flags & 0xf) == OPEN_READ) { // check if file opened in read-only mode
DOS_SetError(DOSERR_ACCESS_DENIED);
return false;
}
if (last_action==READ) fseek(fhandle,ftell(fhandle),SEEK_SET);
last_action=WRITE;
if(*size==0){
return (!ftruncate(fileno(fhandle),ftell(fhandle)));
}
else
{
*size=(Bit16u)fwrite(data,1,*size,fhandle);
+ fflush(fhandle);
return true;
}
}

Until an official solution exists, I found a way to work around the problem. By seeking the current file pointer position after each write, the length of the file is updated on disk and visible to subsequent concurrent handles. It's not necessarily the same as fflush(), but it's enough for Antara. It works with GCC on WinXP, but might not work with other runtime libraries or other operating systems. Run the attached TSR program in DOSBox before starting up Win3 and Antara; but note that the issue causes saved games to be damaged when they are saved, so you will have to create new ones with the TSR loaded. Source code is included in the archive.

Attachments

  • Filename
    FFLUSH.ZIP
    File size
    801 Bytes
    Downloads
    210 downloads
    File license
    Fair use/fair dealing exception

Reply 12 of 37, by paulacchang2

User metadata
Rank Newbie
Rank
Newbie

Awesome! Adding fflush() fixes it. I don't think this should cause any problems with other games, but to be safe, one could execute fflush only if (flags&0x40) != 0:


bool localFile::Write(Bit8u * data,Bit16u * size) {
if ((this->flags & 0xf) == OPEN_READ) { // check if file opened in read-only mode
DOS_SetError(DOSERR_ACCESS_DENIED);
return false;
}
if (last_action==READ) fseek(fhandle,ftell(fhandle),SEEK_SET);
last_action=WRITE;
if(*size==0){
return (!ftruncate(fileno(fhandle),ftell(fhandle)));
}
else
{
*size=(Bit16u)fwrite(data,1,*size,fhandle);
+ if((flags&0x40)!=0)
+ fflush(fhandle);
return true;
}
}

Reply 13 of 37, by ripsaw8080

User metadata
Rank DOSBox Author
Rank
DOSBox Author

DOSBox's current behavior is not the same as DOS, but neither is flushing the handle. Opening files with the DENY NONE flag has no effect on the issue in DOS; only purposely flushing writes with INT 21/68 or loading SHARE.EXE will make revised file sizes visible to additional concurrent handles.

In DOS, the second handle sees the file size as what it was before the first handle wrote to the file (from the directory entry, I guess). In DOSBox, the second handle sees the revised size of the file in blocks of 4kB, i.e. any residual portion less than 4kB is not yet written to disk. It smells like a write buffer is employed by fwrite() or the host OS, so the behavior could vary between C runtime libraries and platforms.

On a side note, DOSBox currently does nothing with INT 21/68 except verify that the handle is good and return an error if necessary. It seems like using fflush() on the real file handle would be a good idea there, but there may be the same C runtime and cross-platform considerations.

Reply 14 of 37, by paulacchang2

User metadata
Rank Newbie
Rank
Newbie

ripsaw8080, I realize the DENY NONE flag doesn't really have an effect, but I was suggesting that perhaps we could infer that programs which have this flag want (or at least will not suffer from) share-like behaviour. However, thanks to your concise and clear explanation, I now understand that this is sort of beside the point, since DOS behaviour isn't actually being replicated anyways (although all the games I have running with DOSBox seem pretty happy with the current DOSBox behaviour).

As another side note, is the following supposed to be reg_bx, rather than reg_bl?

case 0x68:                  /* FFLUSH Commit file */
+ if(DOS_FlushFile(reg_bx)) {
- if(DOS_FlushFile(reg_bl)) {
CALLBACK_SCF(false);
} else {
reg_ax = dos.errorcode;
CALLBACK_SCF(true);
}
break;

Reply 15 of 37, by ripsaw8080

User metadata
Rank DOSBox Author
Rank
DOSBox Author

all the games I have running with DOSBox seem pretty happy with the current DOSBox behaviour

I don't have any solid statistics on this, but I suspect games that try to use concurrent handles on a file are not all that common. 😉

The RBIL says that BX=handle for INT 21/68, but I think 255 is the maximum number of possible handles, and using reg_bl is an easier safeguard than reg_bx&0xff.

Reply 17 of 37, by ripsaw8080

User metadata
Rank DOSBox Author
Rank
DOSBox Author

It does seem like flushing on every write could be a bit much, particularly with a lot of small writes (that's probably why there's a write buffer involved).

Another option is to do the same thing the workaround TSR is doing:

 bool localFile::Write(Bit8u * data,Bit16u * size) {
if ((this->flags & 0xf) == OPEN_READ) { // check if file opened in read-only mode
DOS_SetError(DOSERR_ACCESS_DENIED);
return false;
}
if (last_action==READ) fseek(fhandle,ftell(fhandle),SEEK_SET);
last_action=WRITE;
if(*size==0){
return (!ftruncate(fileno(fhandle),ftell(fhandle)));
}
else
{
*size=(Bit16u)fwrite(data,1,*size,fhandle);
+ fseek(fhandle,0,SEEK_CUR);
return true;
}
}

Seems like it might be less heavy, and the file pointer doesn't actually move. Don't know if it works for other C runtimes, but for some reason it causes the file size on disk to be fully extended, acting similar to a flush.

Reply 19 of 37, by ripsaw8080

User metadata
Rank DOSBox Author
Rank
DOSBox Author

To test the impact on speed of the fflush and fseek approaches, I made an assembly program that creates a new file and writes 10MB to it, one byte at a time. If it isn't a worst-case scenario, it's still pretty bad. I used dynamic core with 100K fixed cycles, and ran each test a few times to make sure there weren't any irregularities.

no flush = 9 seconds
fflush(fhandle); = 52 seconds
fseek(fhandle,0,SEEK_CUR); = 77 seconds
fseek(fhandle,ftell(fhandle),SEEK_SET); = 79 seconds

fflush creates a sizeable hit on performance in this artificially bad scenario, and I'm not really surprised that seek is even worse because it is the flushing effect of the seek that the workaround TSR makes use of.