Jump to content
Search In
  • More options...
Find results that contain...
Find results in...
Sign in to follow this  
Quasar

Chocolate Strife Beta 2

Recommended Posts

Chocolate Strife Beta 2 is now available. A list of what's new is available in the readme-b2.txt file below and inside the zip file.

Note:
*nix users should *NOT* attempt to use the provided source zip file; it is a SVN export which cannot maintain file properties such as line ending styles. They should instead check out the SVN revision 2351 directly from the following URL:
https://chocolate-doom.svn.sourceforge.net/svnroot/chocolate-doom/branches/strife-branch

Share this post


Link to post

Grabbed SVN, compiled under mingw+msys with few warnings, and runs without crashing. I was never a very big fan of Strife so I didn't play much, but this does look like an awesome project.

BTW: Crash if you try to start a new game with no name (ie, choose save slot, then hit enter twice without typing in a name)

Share this post


Link to post

The peasant walking behavior was wrong? I could of sworn that I matched it from the disassembly. Or am I thinking of something else...

Share this post


Link to post
Kaiser said:

The peasant walking behavior was wrong? I could of sworn that I matched it from the disassembly. Or am I thinking of something else...

Definitely something else because I did that part of the code, and I nerfed it up pretty badly in the original - missed some whole portions of the disassembly and what I had really made no sense. It was this issue which was causing the IWAD demo to desync at the 2nd Acolyte if you remember.

natt said:

BTW: Crash if you try to start a new game with no name (ie, choose save slot, then hit enter twice without typing in a name)

Thanks, will investigate.

Share this post


Link to post
Quasar said:

Thanks, will investigate.


As best as I can tell, it goes something like this: Start the executable, quickly select new game, hit enter twice on an empty slot (nothing will happen), and then wait for the "intro sequence" to begin. At that point, it stops responding; GDB shows it's stuck in the do loop at d_main.c:375. Couldn't tell you more than that.

Share this post


Link to post
natt said:

As best as I can tell, it goes something like this: Start the executable, quickly select new game, hit enter twice on an empty slot (nothing will happen), and then wait for the "intro sequence" to begin. At that point, it stops responding; GDB shows it's stuck in the do loop at d_main.c:375. Couldn't tell you more than that.

That loop includes a call to M_Drawer which must be related to this in some manner. First of course I gotta make sure this doesn't happen in vanilla Strife ;)

EDIT: Not only does it not happen in vanilla, but I can't seem to replicate this myself either. Doing exactly as instructed but it's performing as expected - it just sits there and does nothing, which is what vanilla does in the same situation.

Maybe there is some undefined behavior being invoked that causes this only if it's compiled with MinGW? It's worth noting that the code which drives name input is the same as it is in Chocolate DOOM - does this also happen in Chocolate DOOM?

Share this post


Link to post

The "empty slot no name" is a red herring. I'm getting the crash even without entering a name, and sometimes not while putting in the name. It's definitely happening at that first crossfade though. I'll tell you if I figure out any more.

edit: did more gdbing.

d_main.c:386

        done = wipe_ScreenWipe(wipe_ColorXForm
                               , 0, 0, SCREENWIDTH, SCREENHEIGHT, tics);
This never returns true. This can be traced to f_wipe.c:wipe_doColorXForm never returning 1.

Share this post


Link to post
natt said:

The "empty slot no name" is a red herring. I'm getting the crash even without entering a name, and sometimes not while putting in the name. It's definitely happening at that first crossfade though. I'll tell you if I figure out any more.

Ahh OK. You're just ahead of me ;)

EDIT: Hmm. That shouldn't be happening >_> And does not happen, when compiled with MSVC 2008.

EDIT 2: Just for certainty, you are using an unmodified commercial-version Strife 1.2 or 1.31 IWAD file, correct?

Share this post


Link to post

Here's the deal (I think).

f_wipe.c:wipe_doColorXForm has a very "fragile" detection of its end condition; it simply keeps on combining colors until it gets to an iteration where everything matches end_screen.

I can pretty reliably reproduce the crash if I simply scroll (hold DOWN) over the "new game" entries when the wipe occurs. And in situations where it does crash, I see something like this frozen in space:

http://img703.imageshack.us/i/strifecrash.png/

I managed to catch the menu cursor in two places at once. This leads me to believe that the problem is that the interference of M_Drawer () is leading to the finish condition in wipe_doColorXForm never being reached.

Recompiling with the call to M_Drawer () commented out, I find that I can no longer reproduce the crash. I think it has something to do with the location of the cursor being different on the "wipe from" and the "wipe to" screens and M_Drawer () continually redrawing it in the wrong place, but I can't be sure.

Edit: IWAD verified as correct 2fed2031a5b03892106e0f117f17901f

Share this post


Link to post
natt said:

Here's the deal (I think).

f_wipe.c:wipe_doColorXForm has a very "fragile" detection of its end condition; it simply keeps on combining colors until it gets to an iteration where everything matches end_screen.

I can pretty reliably reproduce the crash if I simply scroll (hold DOWN) over the "new game" entries when the wipe occurs. And in situations where it does crash, I see something like this frozen in space:

http://img703.imageshack.us/i/strifecrash.png/

I managed to catch the menu cursor in two places at once. This leads me to believe that the problem is that the interference of M_Drawer () is leading to the finish condition in wipe_doColorXForm never being reached.

Recompiling with the call to M_Drawer () commented out, I find that I can no longer reproduce the crash. I think it has something to do with the location of the cursor being different on the "wipe from" and the "wipe to" screens and M_Drawer () continually redrawing it in the wrong place, but I can't be sure.

Edit: IWAD verified as correct 2fed2031a5b03892106e0f117f17901f

This was in fact one of the first problems we ran into while working on Chocolate Strife, if you dig that old development thread up - the way they programmed wipe_doColorXform is really kind of stupid (and the implementation in Chocolate Strife is 100% accurate to the binary AFAIK).

However, I haven't observed the DOS binary to hang up like this so far. Let me go test it some more and I will come back with a more firm verdict.

If the DOS EXE is NOT subject to this problem, then there must be some other factor making a difference.

Share this post


Link to post

Heh I run into this same problem with Mocha Doom, since the converted code contained that same function and of course I gave it a go. It looks well...quite boring to watch, takes a lot time to complete, and it does not always reliably terminate, let alone that the overall effect looks really terrible.

Share this post


Link to post
Maes said:

Heh I run into this same problem with Mocha Doom, since the converted code contained that same function and of course I gave it a go. It looks well...quite boring to watch, takes a lot time to complete, and it does not always reliably terminate, let alone that the overall effect looks really terrible.

Strife does not have vanilla's broken wipe_doColorXForm. It was rewritten in-place by Rogue to use their XLATAB lump so that it does a translucent crossfade.

The problem is that they wrote it so that it won't stop as long as even a single pixel on the screen changes between the wipe frame and the current frame.

The trigger for the hang is an exact combination of a couple of the menu pointers overlapping in just the right way. However, confusingly, I *cannot* replicate this issue in DOS. I have tried a thousand times and it just will NOT hang up. Something is different there.

Share this post


Link to post
Quasar said:

Strife does not have vanilla's broken wipe_doColorXForm. It was rewritten in-place by Rogue to use their XLATAB lump so that it does a translucent crossfade.

The problem is that they wrote it so that it won't stop as long as even a single pixel on the screen changes between the wipe frame and the current frame.

The trigger for the hang is an exact combination of a couple of the menu pointers overlapping in just the right way. However, confusingly, I *cannot* replicate this issue in DOS. I have tried a thousand times and it just will NOT hang up. Something is different there.


My guess would be some sort of backbuffer/frontbuffer discrepancy? I'm not terribly familiar with the chocolate strife codebase.

Share this post


Link to post

My best hunch is that the difference comes from I_ReadScreen.

Vanilla Strife code - read the current page of VGA memory

void __fastcall I_ReadScreen(int a1)
{
  signed int v1; // ecx@1
  int v2; // esi@1
  signed int v3; // eax@2
  int v4; // edx@2
  char v9; // bl@3

  v2 = a1;
  _DX = 974;
  _AL = 4;
  __asm { out     dx, al          ; EGA: graph 1 and 2 addr reg: }
  v1 = 0;
  do
  {
    _DX = 975;
    _AL = v1;
    __asm { out     dx, al          ; EGA port: graphics controller data register }
    v3 = 0;
    v4 = v2 + v1;
    do
    {
      v4 += 4;
      v9 = *(_BYTE *)(currentscreen + v3++);
      *(_BYTE *)(v4 - 4) = v9;
    }
    while ( v3 < 16000 );
    ++v1;
  }
  while ( v1 < 4 );
}
Chocolate Doom code - copy the one and only SDL video surface:
void I_ReadScreen (byte* scr)
{
    memcpy(scr, I_VideoBuffer, SCREENWIDTH*SCREENHEIGHT);
}
If this isn't it, then I'm completely out of ideas. And also, I don't see any way to "fix" it either. After all I can't really set tweaked Mode 13h and read from the VGA :<

Share this post


Link to post

I've got it and the result is gonna blow some minds - posting a new thread about it.

Share this post


Link to post
natt said:

no wait i just figured it out

Well I was wrong, so I deleted my thread.

Turns out the tweaked Mode 13h that DOOM uses *is* in fact unchained and therefore planar, and this can be seen in the I_UpdateBox function which actually pushes out the pixels - it does the same kind of planar write pattern of every 4th byte followed by changing the page # by writing to VGA register on port 3C5 - dunno how I missed this before.

Anyway, this still leaves me without a really good explanation of what's going on here. :(

Share this post


Link to post
Quasar said:

Well I was wrong, so I deleted my thread.

Turns out the tweaked Mode 13h that DOOM uses *is* in fact unchained and therefore planar, and this can be seen in the I_UpdateBox function which actually pushes out the pixels - it does the same kind of planar write pattern of every 4th byte followed by changing the page # by writing to VGA register on port 3C5 - dunno how I missed this before.

Anyway, this still leaves me without a really good explanation of what's going on here. :(


Well, I'll tell you what I concluded. Perhaps you already know all this though.

In d_main.c:D_Display, we have the following sequence of calls if we're wiping case (lots of other stuff has been omitted):

wipe_StartScreen()
<draw lots of shit for the next tic>
M_Drawer()
NetUpdate()
wipe_EndScreen()
<wipe loop>
The <wipe loop> morphs from the screen captured by wipe_StartScreen() to the screen captured by wipe_EndScreen() while continually calling M_Drawer() along the way. It does this by alpha blending and modifying the current screen, which is also the screen that M_Drawer() draws to.

So in order for the loop to finish successfully, what M_Drawer() puts on the screen during the loop must be the SAME as what it put on to the screen right before wipe_EndScreen(). But here's the problem: if you look at the ways the stuff drawn by M_Drawer() can change, you'll find that NetUpdate() does in fact change it:
NetUpdate() -> D_ProcessEvents() -> M_Responder()
and M_Responder() can change the position of the sigil (which menu item it's pointing to).

So the M_Drawer() call inside the wipe loop draws the sigil in a different place than the "target" screen, stored by wipe_EndScreen(), so the wipe never finishes.

Swapping lines 359 and 360 of d_main.c, NetUpdate() and M_Drawer(), seems to work, as expected.

Share this post


Link to post

Hmm - the thing is, vanilla is capable of calling it from inside NetUpdate as well, though there does seem to be a Chocolate-ism in effect - there is a call below to M_Ticker which exists in neither Strife 1.2 nor in the doom-src-release tag. I'm curious about fraggle's justfication for that change and if it has anything to do with this problem.

EDIT: I moved M_Ticker back where it belongs since there's no justification for calling it from NetUpdate, as all it does is animate the cursor; however, this didn't help so it confirms that it has nothing to do with this problem.

Share this post


Link to post

Seems to be fixed with SVN r2352. I adjusted the screenwipe module to use a temporary screen buffer, which eliminates the issue at its source. Not sure if the resulting behavior is 100% original, but then again 100% original behavior with the screen refresh is impossible due to the missing dirty rects and page flipping systems.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  
×