Jump to content
Search In
  • More options...
Find results that contain...
Find results in...
Eponasoft

C-only source port...

Recommended Posts

So I'm looking for a good source port to begin my game project with. Naturally, I have the original xdoom code, and it's pre-patched for my OS. But I've looked at a few other ports as well, and most of them are coded in C++. I need one that's coded in straight C. I looked at chocolate doom, which is straight C, but it is ridiculously complex and has a lot of things that are unnecessary. The makefile alone reads like a movie script. Odamex was originally the source I was looking at, but it too was converted to C++. So...are there any others that are cross-platform enough to use and coded in straightforward C? The problem with xdoom is that it's a little *too* primitive ad only runs in 8-bit mode...removing the Xlib dependencies would be a major project in and of itself, which is why chocolate doom looked like a good start, since it already uses SDL.

Share this post


Link to post

This is probably your best bet:
http://www.doomworld.com/idgames/index.php?id=11103

This is the source code to Doom3D, a very old directx port of Doom. The code is very simple and based directly off of the 'vanilla' doom source. The only exclusive code to this port is the rendering stuff.

Personally this is probably the most simplistic source port there is.

Share this post


Link to post

WinMBF, which is my SDL port of the DOS Marine's Best Friend source port, has a few less "complex" features than Choco Doom, and is 100% C.

Share this post


Link to post

Hrm...ok, interesting. I downloaded Doom3D and I'll see if I can do anything with it...of course the first step would be ripping out all the D3D code. :)

I could not find the source code for WinMBF though. I was here:

http://www.doomworld.com/idgames/?id=12773

and all the links were dead.

I had also considered using the Heretic engine as a base, since it supports a few more of the features my game requires (such as item inventory), but the silly package manager hosed the port configuration and I can't reset it. :(

EDIT: I also just checked out the Eternity Engine, but it naturally fails to build on my system. Bummer too, as it looks like it supports Heretic, and it's coded in C.

Share this post


Link to post
Eponasoft said:

Hrm...ok, interesting. I downloaded Doom3D and I'll see if I can do anything with it...of course the first step would be ripping out all the D3D code. :)

I could not find the source code for WinMBF though. I was here:

http://www.doomworld.com/idgames/?id=12773

and all the links were dead.


Occuring for me too, try this one: http://ftp.chg.ru/pub/games/idgames/source/winmbf02s.zip

Share this post


Link to post

OK, thanks, this should help a bit. No makefile included and the filenames are first-letter capitalized but none of that's a problem at all. This should not be hard to work with.

EDIT: I'm attempting to build this port now...so far so good, I've run into a few problems along the way but nothing too serious. This is the latest:

p_floor.c:913: error: conflicting types for 'EV_DoElevator'
p_spec.h:888: error: previous declaration of 'EV_DoElevator' was here
*** Error code 1
p_floor.c seems to have the correct declaration; p_spec.h appears to be wrong. Modifying p_spec.h allows the build to continue up until p_mobj.c, where yet another error has taken place. The editing continues...

EDIT2: All of the files eventually compiled to object code...but now, none of them will link. The screen becomes littered with undefined references. It's likely an issue with my makefile, which I will eventually solve.

EDIT3: I have solved pretty much all of them by making sure to also include other C files that were not part of the original set of sources. However, I have now run into another problem, and it seems to be Microsoft-specific...strnicmp, stricmp, and strlwr. strlwr seems to be similar to tolower, and the others are string comparison functions. I just have to redefine them, I guess...

EDIT4: I was able to redefine strnicmp and stricmp to alternate functions...still working on strlwr though. :) And I forgot yet another source...version.c, which is just a tiny little thing but enough to cause yet another compilation headache.

EDIT5: After a long search on google and IRC, I finally found all I needed to get the source to fully build and produce a binary. Of course, when it went to run, I got this:
Could not find config variable "friend_distance"
which automatically made it terminate...kind of silly imo. Oh well...I'll keep messing with it.

EDIT6: I modified the source to skip over config options it could not find by changing I_Error to printf on line 3668 of m_menu.c. After building it again, the program started up. Of course, it then proceeded to crash immediately as soon as the window popped up. Woot...
Looking in .
IWAD found: ./doom.wad
DOOM Registered version
                            DOOM Registered Startup v2.03
Built on Aug 31 2009
M_LoadDefaults: Load system defaults.
V_Init: allocate screens.
W_Init: Init WADfiles.
 adding ./doom.wad

M_Init: Init miscellaneous info.
Could not find config variable "friend_distance"
R_Init: Init DOOM refresh daemon - [ ................. ]
R_InitData
R_InitPlanes
R_InitLightTables
R_InitSkyMap
R_InitTranslationsTables

P_Init: Init Playloop state.
I_Init: Setting up machine state.
I_InitSound:
Configured audio device with 512 samples/slice.
I_InitMusic: Using SDL_mixer.
D_CheckNetGame: Checking network game status.
startskill 2  deathmatch: 0  startmap: 1  startepisode: 1
player 1 of 1 (1 nodes)
S_Init: Setting up sound.
S_Init: default sfx volume 8
HU_Init: Setting up heads up display.
ST_Init: Init status bar.
Segmentation fault (core dumped)
EDIT7: I have isolated the source of the crash; function TryRunTics() is the culprit. Now to dissect that function to find the specific line of code responsible...

EDIT8: I have traced it back to this line exactly:
while (lowtic < gametic/ticdup + counts)
which indicates that there is a division error here. How odd...

EDIT9: I tested the variables right before the loop, and here was the result:
lowtic 5 - gametic 0 - ticdup 1 - counts 5
Setting gametic to 1 if it was at 0 had no effect on the outcome...it still crashes. :(

Share this post


Link to post

You sure it's that line? IIRC division by zero raises a floating point exception error instead of a segmentation fault (which is usually a NULL or bad pointer).

P.S. be sure to disable optimisations at this early stage (-O0 option to gcc), as it makes debugging harder.

Share this post


Link to post

I'm positive. I retyped that exact comparison on a line right above it to create an independent comparison, then placed printf lines before and after it. The program still segfaulted, so the issue has to involve lowtic < gametic/ticdup + counts. I temporarily recoded it to match Heretic's code, which removes the ticdup division, but got the same result.

This is undoubtedly the oddest thing I've ever seen. :/

EDIT: It has something to do with lowtic. The program segfaults anytime lowtic is used in a comparison.

Share this post


Link to post

It simply isn't possible for a program to segfault by accessing integer variables unless a compiler error has resulted in misgenerated code, and that is an event so exceptionally rare that it has not occurred once during my entire programming "career" (I wish I could remove those quotation marks...)

However, it is quite easy for a stack dump to point to the wrong crash location when the stack has been corrupted. This has happened to me more times than I could count. Stack corruption is usually caused by buffer overflows and underflows. It is also possible to get a garbage stack dump if your IP jumps outside the program code, but that is understandably a more rare occurance and is virtually always obvious when it happens (IP of the crash will be in some ridiculous location such as 0xFFFFFFFF or 0x00000000 or 0xDEADBEEF).

I would suggest that something of the former is going on here, *especially* if this is WinMBF that is crashing like this. If you are using the Build 2 source zip from /idgames, I do *not* suggest it (and I told Kaiser this before...)

Instead you need to do a SVN checkout of the source repository, which is located at http://mancubus.net/svn/hosted/winmbf - the current trunk revision has a HUGE number of fixes to BOOM and MBF fatal errors, which for all I know may be what's causing your problem. At any rate, it cannot hurt to have the possibilities narrowed down.

Also, and this is something I wish I didn't have to tell people any more, but if you are using a multicore processor, you must set the processor affinity of the WinMBF process to "1" or else it will crash at random. Even in the trunk I have not yet gotten around to copying in the i_cpu.c module from the Eternity Engine which contains a workaround for this problem. This is a bug in the SDL_mixer and/or SDL audio libraries, and cannot be repaired by doing anything to the port using the library.

A crash on the SDL_mixer thread would appear most likely like a crash in the main loop of the program if your debugger attaches to the wrong thread (and in my experience this is a very common phenomenon, especially with Visual C++ under Windows). If possible, check the location of the other threads, as the one you're looking at may simply be stopped and not crashed.

Share this post


Link to post

I'll check out the updated source code, thanks.

I do not typically tend to use a debugger. I will only use one if I have exhausted all logical code issue possibilities. I do not have a multicore processor (just a celery, hehe), and it doesn't crash at random but at that specific place. Hopefully the updated source code will remedy the issue.

Interestingly enough, if I terminate TryRunTics early (using a return; before the offending code), the game will start up and function somewhat...the render won't display, but the menu will function and the game can be exited normally.

Share this post


Link to post
Eponasoft said:

I'll check out the updated source code, thanks.

I do not typically tend to use a debugger. I will only use one if I have exhausted all logical code issue possibilities. /B]



With that attitude you are making your life much more difficult than you need. Debuggers are there precisely for what you refuse to do here.

Share this post


Link to post
Quasar said:

WinMBF, which is my SDL port of the DOS Marine's Best Friend source port, has a few less "complex" features than Choco Doom, and is 100% C.


What do you mean by "complex" features? You mean hacks to make it more like vanilla?

Share this post


Link to post
Graf Zahl said:

With that attitude you are making your life much more difficult than you need. Debuggers are there precisely for what you refuse to do here.

Some programmers are obstinate. Really. Because they are "cool hackers". They prefer to use "notepad" and printf/MessageBox "before and after" instead of debuging. They have no alternative with vi. You can't change these things. They will stay in stone age forever. Because "it is enough" for them.

Share this post


Link to post
Graf Zahl said:

With that attitude you are making your life much more difficult than you need. Debuggers are there precisely for what you refuse to do here.

Not really. I have coded without a debugger for over 20 years. Plus, it's not a refusal to use one. I will very occasionally use one when there is a problem I can't resolve otherwise. For my own stuff, I test my application at regular intervals for issues and correct any that pop up immediately, so my need for a debugger in my own program is pretty rare. It's only when using someone else's code that I would usually ever need one. This might have ended up being one of those times. 99.99% of the issues encountered while building the original source were corrected by simply tracing the source code. If, after building this latest source, issues still appear that I can't correct normally, then I will likely use gdb to see if I can get more details.

entryway, you crack me up. I have used text editors for writing code for a long, long time. Now I use kwrite, because it starts quickly and has line numbers...no other reasons. I think it may be because my first PC programming environment was QBASIC, which has no syntax highlighting, and before that, I coded in machine code on the Commodore 64 which, again, has no syntax highlighting in the code monitor. IDEs tend to bug me, especially ones that have code completion (like VB6). My methods are not yours, but you don't see me trying to insult you because of your choices.

Well anyways, I've got all of the latest source now...it'll take some time to make the necessary changes to compile on my system...probably about an hour or so. No biggie.

Share this post


Link to post
Eponasoft said:

Not really. I have coded without a debugger for over 20 years.



Gotta agree with entryway here. :P

Amazing that you managed to create something usable then. :D
I've been programming for over 20 years, too, but ever since I had my first experience of a debugger (Turbo Pascal 6.0 if I am not mistaken) it has become a tool that has saved me countless hours of wasted time.

Share this post


Link to post
Eponasoft said:

99.99% of the issues encountered while building the original source were corrected by simply tracing the source code

You spend your time non efficiently. Almost every even little problem can be solved with debugger faster. You can solve everything without them (of course), but it is wrong way. Debuggers ARE for quick resolving of issues.

Share this post


Link to post

Well, I'm not going to argue the merits of debuggers. If it works for someone, then that's just fine. I have always clung fast to the belief that code written properly the first time will not need debugging (Microsoft would do well to learn this lesson...). But enough of this particular subject.

I ran across the segfault issue with the newest source and it is highly likely to be in the same place. I have compiled with -g and will see if gdb can offer any insight.

EDIT: gdb locks up the system when it gets to the segfault. Not very helpful at all. :(

Share this post


Link to post
Eponasoft said:

I ran across the segfault issue with the newest source and it is highly likely to be in the same place. I have compiled with -g and will see if gdb can offer any insight.

Something is wrong with non-Windows targets. Winmbf compiles (and works fine after that) in one click with VC6 (just press F5). I used winmbf for fixing incompatibilities for MBF emulation modes of PrBoom.

Share this post


Link to post

Hrm...bummer. :(

Well, I wrote down what gdb was able to write out before locking up X...good thing pen and paper rarely crashes. :)

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x28701040 (LWP 100117)]
0x558b10ec in ?? ()
(gdb)
I have Visual Studio 98 on two of the Windows systems here so it would be easy to build it on one of those, but that defeats the purpose of building this on a non-Windows system...

Share this post


Link to post

That crash tells you more than you think. It crashed clearly outside the valid code. One thing's sure though: This one's not easy to find no matter what you do.

Share this post


Link to post

The annoying thing is that I know exactly where it crashes, down to the line in the source code. It's line 743 in d_net.c:

while (lowtic < gametic/ticdup + counts)
This was the cause last time, and is still the cause this time. But this is completely illogical, unless the code generation is malformed, as Quasar suggested.

EDIT: I used gdb to get data on the core dump. Here is the result:
Core was generated by `newdoom'.
Program terminated with signal 11, Segmentation fault.
Reading symbols from /usr/local/lib/libSDL-1.2.so.11...done.
Loaded symbols for /usr/local/lib/libSDL-1.2.so.11
Reading symbols from /lib/libthr.so.3...done.
Loaded symbols for /lib/libthr.so.3
Reading symbols from /usr/local/lib/libSDL_image-1.2.so.1...done.
Loaded symbols for /usr/local/lib/libSDL_image-1.2.so.1
Reading symbols from /usr/local/lib/libSDL_sound.so.1...done.
Loaded symbols for /usr/local/lib/libSDL_sound.so.1
Reading symbols from /usr/local/lib/libSDL_mixer-1.2.so.2...done.
Loaded symbols for /usr/local/lib/libSDL_mixer-1.2.so.2
Reading symbols from /usr/local/lib/libSDL_net-1.2.so.0...done.
Loaded symbols for /usr/local/lib/libSDL_net-1.2.so.0
Reading symbols from /lib/libc.so.7...done.
Loaded symbols for /lib/libc.so.7
Reading symbols from /lib/libm.so.5...done.
Loaded symbols for /lib/libm.so.5
Reading symbols from /usr/local/lib/libiconv.so.3...done.
Loaded symbols for /usr/local/lib/libiconv.so.3
Reading symbols from /usr/lib/libvgl.so.5...done.
Loaded symbols for /usr/lib/libvgl.so.5
Reading symbols from /usr/local/lib/libaa.so.1...done.
Loaded symbols for /usr/local/lib/libaa.so.1
Reading symbols from /usr/lib/libusbhid.so.3...done.
Loaded symbols for /usr/lib/libusbhid.so.3
Reading symbols from /lib/libncurses.so.7...done.
Loaded symbols for /lib/libncurses.so.7
Reading symbols from /usr/local/lib/libX11.so.6...done.
Loaded symbols for /usr/local/lib/libX11.so.6
Reading symbols from /usr/local/lib/libxcb.so.2...done.
Loaded symbols for /usr/local/lib/libxcb.so.2
Reading symbols from /usr/local/lib/libXau.so.6...done.
Loaded symbols for /usr/local/lib/libXau.so.6
Reading symbols from /usr/local/lib/libXdmcp.so.6...done.
Loaded symbols for /usr/local/lib/libXdmcp.so.6
Reading symbols from /usr/lib/librpcsvc.so.4...done.
Loaded symbols for /usr/lib/librpcsvc.so.4
Reading symbols from /usr/local/lib/libmikmod.so.2...done.
Loaded symbols for /usr/local/lib/libmikmod.so.2
Reading symbols from /usr/local/lib/libvorbis.so.4...done.
Loaded symbols for /usr/local/lib/libvorbis.so.4
Reading symbols from /usr/local/lib/libvorbisfile.so.5...done.
Loaded symbols for /usr/local/lib/libvorbisfile.so.5
Reading symbols from /usr/local/lib/libFLAC.so.10...done.
Loaded symbols for /usr/local/lib/libFLAC.so.10
Reading symbols from /usr/local/lib/libogg.so.5...done.
Loaded symbols for /usr/local/lib/libogg.so.5
Reading symbols from /usr/local/lib/libspeex.so.1...done.
Loaded symbols for /usr/local/lib/libspeex.so.1
Reading symbols from /usr/local/lib/libXrender.so.1...done.
Loaded symbols for /usr/local/lib/libXrender.so.1
Reading symbols from /usr/local/lib/libXcursor.so.1...done.
Loaded symbols for /usr/local/lib/libXcursor.so.1
Reading symbols from /usr/local/lib/libXfixes.so.3...done.
Loaded symbols for /usr/local/lib/libXfixes.so.3
Reading symbols from /libexec/ld-elf.so.1...done.
Loaded symbols for /libexec/ld-elf.so.1
#0  0x558b10ec in ?? ()
[New Thread 0x28701040 (LWP 100115)]

Share this post


Link to post

I doubt it's that line. How do you verify?

Since it's a loop command, maybe something happens that makes something in the loop go crazy.

Share this post


Link to post

It is indeed that line, and I verified it last time and this time as well. Last time, I used a printf before and after the line in question, which allowed me to see that it was exactly that line. This time, I put a return; right before it and ran it (this makes the program run but with no display except the menu), then right after it and ran it...this causes the crash since that line of code executes. As an aside, last time I had commented that line as well as a couple of lines after it...depending on which lines I commented, I could get the crash to happen again even without that line executing, which leads me to believe that it's not the code per se but a condition in the build process itself that generates faulty object code. The $100,000 question is...what is it? :)

EDIT: It's happening all throughout the function. One thing that has bugged me from the start was the usage of MAXINT. There are two references in this function...line 683 sets lowtic to MAXINT, and 746 sets lowtic to D_MAXINT. I set these to 0 instead, and got the same result as return;'ing early from the function. No crash, but no display. Setting lowtic to any value other than 0 causes the program to segfault once again. This gets weirder by the minute...

Share this post


Link to post

Don't count on printf to be the most accurate measure of when a program crashes. Use fprintf to stderr instead.

Share this post


Link to post

That wasn't the only measure employed, it was just one. Using return; at specific points of the function and noting the result was another part of it.

Well, here's my makefile. I don't know if this has anything to do with the build issues or not, though I highly doubt it does. Note that it is platform-specific; it is designed to only run on my system. Later on, I will write one more "user friendly", but for now, for this build, this is what it is. Since this source did not come with a makefile (intended for Microsoft's compilers, it seems), I had to write my own. This is loosely based on the original xdoom makefile as well as makefiles I've used for my own SDL-based projects.

CFLAGS= -I/usr/local/include -L/usr/local/lib -O0 -g
LIBS= -lSDL -lSDL_net -lpthread -lSDL_sound -lSDL_mixer

all: newdoom
 
newdoom:  doomdef.o doomstat.o dstrings.o am_map.o d_deh.o d_main.o d_items.o d_net.o \
		 f_finale.o f_wipe.o g_game.o hu_stuff.o hu_lib.o i_main.o mmus2mid.o \
		 i_system.o i_sound.o i_video.o i_net.o info.o m_menu.o m_misc.o m_argv.o \
		 m_bbox.o m_cheat.o m_random.o p_ceilng.o p_doors.o p_enemy.o p_genlin.o \
		 p_floor.o p_inter.o p_lights.o p_map.o p_maputl.o p_plats.o \
		 p_pspr.o p_setup.o i_stretch.o p_sight.o p_spec.o \
		 p_switch.o p_mobj.o p_telept.o p_tick.o p_saveg.o p_user.o \
		 r_bsp.o r_data.o r_draw.o r_main.o r_plane.o r_segs.o \
		 r_sky.o r_things.o s_sound.o sounds.o st_lib.o st_stuff.o version.o \
		 tables.o v_video.o w_wad.o wi_stuff.o z_zone.o

	cc $(CFLAGS) i_main.o doomdef.o doomstat.o dstrings.o am_map.o d_main.o d_items.o d_net.o \
		 f_finale.o f_wipe.o g_game.o hu_stuff.o hu_lib.o i_system.o i_sound.o i_video.o \
		 i_net.o info.o m_menu.o m_misc.o m_argv.o m_bbox.o d_deh.o m_cheat.o mmus2mid.o \
		 m_random.o p_ceilng.o p_doors.o p_enemy.o p_floor.o p_inter.o p_lights.o p_map.o p_genlin.o \
		 p_maputl.o p_plats.o p_pspr.o p_setup.o p_sight.o p_spec.o p_switch.o p_mobj.o \
		 p_telept.o p_tick.o p_saveg.o p_user.o r_bsp.o r_data.o r_draw.o r_main.o i_stretch.o \
		 r_plane.o r_segs.o r_sky.o r_things.o s_sound.o sounds.o st_lib.o st_stuff.o \
		 tables.o v_video.o w_wad.o wi_stuff.o z_zone.o version.o $(LIBS) -o newdoom

.c.o:
	cc -c $(CFLAGS) $<

clean:
	rm -f newdoom *.o

 

Share this post


Link to post

Wow, some really great investigation is going on here. How's your amazing working style going to help now? For god's sake! Use the debugger like it's supposed to be used! Break before the problem spot and then single step through your code until you find what's up. I'm sure that Entryway or me would have long found the problem instead of messing around helplessly with insufficient tools!

Share this post


Link to post

I wish I had any clue what was going on here because I'd fix it in a heartbeat. Surely other ports of the BOOM/MBF codebase to Linux had to run into this at some point?

It is clear that the stack is trashed. Stack dumps will not help with finding this, so in fact printf debugging tricks may be the only sane route to narrowing it down.

What you need to look for at this point, IMO, are buffer over/underflows in on-stack buffers such as character arrays. Those are almost always the culprit with this kind of crash. Because the stack grows downward, writing off the end of a string buffer on the stack trashes the return address and causes you to jump out of the program.

I will try to look for such potential issues in the code myself, but without the ability to compile and run it on Linux myself, I can only do so much.

---Edit---
IDEA: You're not trying to compile this as 64-bit code are you?

Share this post


Link to post

Maybe the guy thinks of a debugger as a generic register dump on a disassembler screen. That too wouldn't help with tracking issues with a specific source code line, unless it was tightly integrated with the object code/IDE/debug runtime etc. One more reason to use an IDE with source code debugging, IMO, rather than use a general purpose disassembler/debugger. Unless you're so good that you can mentally link generated machine code to its source ;-)

Share this post


Link to post

Graf, the problem spot takes place less than 0.2 seconds after typing "run" in gdb. So unless it can be broken before that, that's not going to help too much. However, if you have any way of gaining access to a FreeBSD 7.2 machine (vmware is a great method, it's how I ran FBSD before installing it directly), then I will gladly send you the broken binary and the source code to see if you can find the issue as easily as you claim to be able to do.

Quasar, I don't know if it would work in Linux or not...there seem to be defines for it but I don't have a Linux system to test on either. I'm building for 32 bit though so that's can't be the problem, fortunately. I'll see if I can find any potential issues with overflows though, that is logical. Thanks for helping with this; I do like this particular source code and hope I can get it working. ulimit reports unlimited so at least I know it's not a stack size issue...

Share this post


Link to post

I had another idea. It seems you are not defining any of the symbols that are defined by the Windows project.

For Debug builds, the following symbols should be defined:
_DEBUG, MY_SDL_VER, DOGS, BETA, RANGECHECK, INSTRUMENTED

In Release builds:
NDEBUG, MY_SDL_VER, DOGS, BETA

This is at least responsible for the mod you had to do to the config file - the friend_distance option is probably inside an #ifdef DOGS because most of the friendly monster code is in that define. Unfortunately, Lee Killough was apparently less than thorough in actually making sure that MBF could build and run with those features disabled...

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
×