typedef
and struct
not used internally (used only for public data: sectortype
, walltype
and spritetype
). Only arrays of primitive data types are used (for example: GRP file system ): static long numgroupfiles = 0; static long gnumfiles[MAXGROUPFILES]; static long groupfil[MAXGROUPFILES] = {-1,-1,-1,-1}; static long groupfilpos[MAXGROUPFILES]; static char *gfilelist[MAXGROUPFILES]; static long *gfileoffs[MAXGROUPFILES]; static char filegrp[MAXOPENFILES]; static long filepos[MAXOPENFILES]; static long filehan[MAXOPENFILES]
inside (long x, long y, short sectnum){ walltype *wal; long i, x1, y1, x2, y2; unsigned long cnt; if ((sectnum < 0) || (sectnum >= numsectors)) return(-1); cnt = 0; wal = &wall[sector[sectnum].wallptr]; i = sector[sectnum].wallnum; do{ y1 = wal->yy; y2 = wall[wal->point2].yy; if ((y1^y2) < 0){ x1 = wal->xx; x2 = wall[wal->point2].xx; if ((x1^x2) >= 0) cnt ^= x1; else cnt ^= (x1*y2-x2*y1)^y2; } wal++; i--; } while (i); return(cnt>>31); }
static long xb1[MAXWALLSB], yb1[MAXWALLSB], xb2[MAXWALLSB], yb2[MAXWALLSB]; static long rx1[MAXWALLSB], ry1[MAXWALLSB], rx2[MAXWALLSB], ry2[MAXWALLSB]; static short p2[MAXWALLSB], thesector[MAXWALLSB], thewall[MAXWALLSB];
long
type engine assumes that the data will always be 32 bits long.I regretfully closed the forum on the site. Because of the spam bots, it became impossible to manage it, and although there is valuable content in the posts, my time and the moderator time are not worth it.
If you want to keep in touch with the community, then I suggest to refer to the forums on Duke4.net.
long
type was used everywhere, because during development it was believed that this type would always be 32 bits long. This is one of the reasons why the engine could not be compiled in 64-bit mode. Used int32_t
from standard inttypes.h
.char
for arithmetic operations: since depending on the platform it can be signed
or unsigned
, using char
for mathematical calculations led to an unpleasant shift; char
should only be used for strings. For arithmetic operations in Build , int8_t
or uint8_t
from inttypes.h
now explicitly used, which guarantees the presence of a sign.Engine.c
: approximately 95% of the code.ac
: contains a rough C implementation of what was once an optimized assembler.cache1d.c
: contains the caching system and the GRP file system.Engine.c
: Now 50% of the code is in it.display.c
: buffers of SDL surfaces in which the screen is rendered, palette utilities.draw.c
: implementation of assembler procedures in C.tiles.c
: sprite engine.filesystem.c
: everything to create an abstraction of the GRP file system.network.c
: multiplayer mode is not here.cache.c
: random memory allocator and caching service.math.c
: most fixed-point arithmetic functions here.Engine.c
into a frontend and backend in imitation of the Quake3 / Doom3 architecture, which consists of two parts, exchanging data via the stack. But as a result, I decided that I would be too distant from the spirit of the original engine, so I rejected this idea.struct
, but inside everything was organized through arrays of primitive data types, without a struct
and typedef
. long numgroupfiles = 0; long gnumfiles[MAXGROUPFILES]; long groupfil[MAXGROUPFILES] = {-1,-1,-1,-1}; long groupfilpos[MAXGROUPFILES]; char *gfilelist[MAXGROUPFILES]; long *gfileoffs[MAXGROUPFILES]; char filegrp[MAXOPENFILES]; long filepos[MAXOPENFILES]; long filehan[MAXOPENFILES];
// GRP: // - 12 // - 4 typedef uint8_t grpIndexEntry_t[16]; typedef struct grpArchive_s{ int32_t numFiles ;// . grpIndexEntry_t *gfilelist ;//, . int32_t *fileOffsets ;//, . int32_t *filesizes ;//, . int fileDescriptor ;//fd . uint32_t crc32 ;// GRP: Duke Shareware, Duke plutonimum .... } grpArchive_t; // GRP typedef struct grpSet_s{ grpArchive_t archives[MAXGROUPFILES]; int32_t num; } grpSet_t;
static long xb1[MAXWALLSB], yb1[MAXWALLSB], xb2[MAXWALLSB], yb2[MAXWALLSB]; static long rx1[MAXWALLSB], ry1[MAXWALLSB], rx2[MAXWALLSB], ry2[MAXWALLSB]; static short p2[MAXWALLSB], thesector[MAXWALLSB], thewall[MAXWALLSB];
enum vector_index_e {VEC_X=0,VEC_Y=1}; enum screenSpaceCoo_index_e {VEC_COL=0,VEC_DIST=1}; typedef int32_t vector_t[2]; typedef int32_t coo2D_t[2]; // , . // . typedef struct pvWall_s{ vector_t cameraSpaceCoo[2]; // . vector_index_e. int16_t sectorId; // , , . int16_t worldWallId; // . coo2D_t screenSpaceCoo[2]; // . screenSpaceCoo_index_e. } pvWall_t; // . pvWall_t pvWalls[MAXWALLSB];
enum
or #define
will significantly improve readability of the code. long globalzd, globalbufplc, globalyscale, globalorientation; long globalx1, globaly1, globalx2, globaly2, globalx3, globaly3, globalzx; long globalx, globaly, globalz; static short sectorborder[256], sectorbordercnt; static char tablesloaded = 0; long pageoffset, ydim16, qsetmode = 0;
/* FCS: ( - nextsector >= 0). , . */ static void scansector (short sectnum) { //, , . short sectorsToVisit[256], numSectorsToVisit; . . . }
int32_t initgroupfile(const char *filename) { uint8_t buf[16] ; int32_t i, j, k ; grpArchive_t* archive ; uint8_t crcBuffer[ 1 << 20] ; printf("Loading %s ...\n", filename) ; . . . }
chkstk
results in a stack overflow, which is not good at chkstk
digesting. This code will run normally in Clang on Mac OS X.Source: https://habr.com/ru/post/323684/
All Articles