Skip to content

Commit

Permalink
Add readme, screenshots, translucent enemies
Browse files Browse the repository at this point in the history
  • Loading branch information
Swizpig committed Jan 26, 2020
1 parent 142bd59 commit 5d1aa64
Show file tree
Hide file tree
Showing 27 changed files with 324 additions and 25 deletions.
39 changes: 39 additions & 0 deletions README
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
ZGLOOM

A re-implementation of Amiga FPS Gloom

INSTRUCTIONS
Drop everything in the bin folder in the root of Gloom (ie, above the misc/, pics/ etc dirs). Run the -zm exe for Zombie Massacre as that game moves some files around.
Will need the VS2013 runtime.

CONTROLS
Cursors, left alt to strafe, left ctrl to fire. F1 skips level. F12 toggles fullscreen. PrintScreen dumps a bitmap.

TODO
-Backend of the renderer is mostly mine, and is flaky. There's Z-fighting that doesn't exist in the original, for instance
-Object scaling not done
-Key repeat on fire needs adding
-Weapons reset on new level
-Sound is deafening on occasion, need variable volume playback and priority system
-Many monsters are missing their logic still
-No HUD and no way to actually die yet
-Crashes on game complete
-No title screen yet
-No blood effects
-No spark effects
-LibXMP's MED playback isn't great on some tunes

LICENSE
Dunno. The Gloom source release says only the .s and .bb2 files are open source, but the Gloom executable bakes in some maths lookup tables (but then, they are generated by the .bb2 files), bullet and sparks graphics, and
the title screen for Classic Gloom. I probably won't add the latter and just display the Black Magic image, or something.

Uses LibXMP for MED playback
http://xmp.sourceforge.net/

Uses SDL2 and SDL2 mixer
https://www.libsdl.org/

DeCrunchmania C code by Robert Leffman, licence unknown
http://aminet.net/package/util/pack/decrunchmania_os4


Binary file modified bin/zgloom.exe
Binary file not shown.
Binary file modified bin/zgloom_zm.exe
Binary file not shown.
11 changes: 11 additions & 0 deletions config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,17 @@ namespace Config
#endif
}

std::string GetMiscDir()
{
#if ZOMBIE_MASSACRE
std::string result = "stuf/";
return result;
#else
std::string result = "misc/";
return result;
#endif
}

std::string GetPicsDir()
{
#if ZOMBIE_MASSACRE
Expand Down
1 change: 1 addition & 0 deletions config.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ namespace Config
std::string GetScriptName();
std::string GetPicsDir();
std::string GetLevelDir();
std::string GetMiscDir();
std::string GetObjectFilename(ObjectGraphics::ObjectGraphicType i);
std::string GetGoreFilename(ObjectGraphics::ObjectGraphicType i);
std::string GetSoundFilename(SoundHandler::Sounds i);
Expand Down
87 changes: 83 additions & 4 deletions font.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,84 @@ void Font::SetPal(SDL_Surface* palsurface)
}
}

bool Font::Load2(CrmFile& file)
{
w = 8;
h = 10;

for (int i = 0; i < glyphs; i++)
{
uint32_t pos = Get32(file.data + 4 + 4 * i);

uint32_t shapepos = pos + Get32(file.data + pos);
uint32_t maskpos = pos + 10;

pos += 4;
uint32_t modulo = Get16(file.data + pos);

pos += 2;
uint32_t widthheight = Get16(file.data + pos);

uint32_t width = (widthheight & 0x3F) * 16;
uint32_t height = (widthheight >> 6);

width = modulo * 8;

surfaces[i] = SDL_CreateRGBSurface(0, width, height, 8, 0, 0, 0, 0);
SDL_SetColorKey(surfaces[i], 1, 0);

//printf("%i %i %i %i\n", shapepos, maskpos, width, height);

// assume always 2 bitplanes?

for (uint32_t plane = 0; plane < 2; plane++)
{
for (uint32_t y = 0; y < height; y++)
{
for (uint32_t x = 0; x < width; x++)
{
uint8_t thebyte = file.data[maskpos + x / 8 + y *((width + 7) / 8) + plane*height*((width + 7) / 8)];

if (plane == 0)
{
((char*)surfaces[i]->pixels)[x + y*surfaces[i]->pitch] = 0;
}

if (thebyte & (1 << (7 - (x % 8))))
{
((char*)surfaces[i]->pixels)[x + y*surfaces[i]->pitch] |= (1 << plane);
}
}
}

// now the palette

uint32_t pos = Get32(file.data);
int colnum = 0;
while (pos < file.size)
{
SDL_Color col;
col.a = 0xFF;
col.r = file.data[pos + 0] & 0xf;
col.g = file.data[pos + 1] >> 4;
col.b = file.data[pos + 1] & 0xF;

col.r <<= 4;
col.g <<= 4;
col.b <<= 4;

SDL_SetPaletteColors(surfaces[i]->format->palette, &col, colnum, 1);

colnum++;
pos += 2;
}
}
}
return true;
}

bool Font::Load(CrmFile& file)
{
bool G2mode = false;
w = 6;
h = 8;

Expand All @@ -42,14 +117,14 @@ bool Font::Load(CrmFile& file)

width = modulo * 8;

surfaces[i] = SDL_CreateRGBSurface(0, width, height / (G2mode?1:7), 8, 0, 0, 0, 0);
surfaces[i] = SDL_CreateRGBSurface(0, width, height / 7, 8, 0, 0, 0, 0);
SDL_SetColorKey(surfaces[i], 1, 0);

//printf("%i %i %i %i\n", shapepos, maskpos, width, height);

// assume always 7 bitplanes?

for (uint32_t y = 0; y < height / (G2mode ? 1 : 7); y++)
for (uint32_t y = 0; y < height / 7; y++)
{
for (uint32_t x = 0; x < width; x++)
{
Expand Down Expand Up @@ -142,7 +217,11 @@ void Font::PrintMessage(std::string message, int y, SDL_Surface* dest)
}
else if (c == ':')
{
Blit(xstart, y, 37, dest);
Blit(xstart, y, 38, dest);
}
else if (c == 127) // what is this?
{
Blit(xstart, y, 39, dest);
}
}

Expand Down
1 change: 1 addition & 0 deletions font.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class Font
public:

bool Load(CrmFile& file);
bool Load2(CrmFile& file);
void SetPal(SDL_Surface* palsurface);
void Blit(int x, int y, int character, SDL_Surface* dest);
void PrintMessage(std::string message, int y, SDL_Surface* dest);
Expand Down
4 changes: 2 additions & 2 deletions gamelogic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -820,8 +820,8 @@ void GameLogic::ObjectCollision()
o.data.ms.washit = 0;

// note goes back to the outer loop in the original? But that seems to mess with the asymettric nature of the collision system?
//break;
continue;
// UPDATE: this may be way objects get added to both the back and front of the list
break;
}

if ((o.data.ms.collwith & o2.data.ms.colltype) == 0)
Expand Down
2 changes: 1 addition & 1 deletion gamelogic.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class GameLogic

bool Collision(bool event, int32_t x, int32_t z, int32_t r, int32_t& overshoot, int32_t& closestzone);
bool AdjustPos(int32_t& overshoot, Quick& x, Quick& z, int32_t r, int32_t& closestzone);
void AddObject(MapObject o) { gmap->GetMapObjects().push_back(o); };
void AddObject(MapObject o, bool first) { if (first) gmap->GetMapObjects().push_front(o); else gmap->GetMapObjects().push_back(o); };
uint8_t PickCalc(MapObject& o);

struct weapontableentry { int32_t hitpoint; int32_t damage; int32_t speed; std::vector<Shape>* shape; SoundHandler::Sounds sound; };
Expand Down
17 changes: 16 additions & 1 deletion gloommap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,7 @@ bool GloomMap::Load(const char* name, ObjectGraphics* nobj)
o.hitpoints = objectlogic->objectlogic[o.t].hitpoints;
o.weapon = objectlogic->objectlogic[o.t].weapon;
o.hurtpause = objectlogic->objectlogic[o.t].hurtpause;
o.blood = objectlogic->objectlogic[o.t].blood;
}

// load wall anims
Expand Down Expand Up @@ -552,7 +553,15 @@ void GloomMap::ExecuteEvent(uint32_t e, bool& gotele, Teleport& teleout)

CalcVecs(mo);

mapobjects.push_back(mo);
// ordering seems needed for collison?
if ((mo.t == ObjectGraphics::OLT_PLAYER1) || (mo.t == ObjectGraphics::OLT_PLAYER1))
{
mapobjects.push_front(mo);
}
else
{
mapobjects.push_back(mo);
}
}
}

Expand Down Expand Up @@ -793,6 +802,7 @@ MapObject::MapObject(Object m)
data.ms.weapon = m.weapon;
data.ms.hurtwait = 0;
data.ms.hurtpause = m.hurtpause;
data.ms.blood = m.blood;

switch (t)
{
Expand Down Expand Up @@ -826,6 +836,11 @@ MapObject::MapObject(Object m)
data.ms.hit = NullLogicComp;
data.ms.die = BlowObjectNoChunks;
break;
case ObjectGraphics::OLT_LIZARD:
data.ms.logic = LizardLogic;
data.ms.hit = LizHurt;
data.ms.die = BlowObject;
break;
case ObjectGraphics::OLT_WEAPON1:
case ObjectGraphics::OLT_WEAPON2:
case ObjectGraphics::OLT_WEAPON3:
Expand Down
3 changes: 3 additions & 0 deletions gloommap.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ class Object
int16_t hitpoints;
int16_t weapon;
int16_t hurtpause;
uint16_t blood;
std::vector<Shape>* shape;
};

Expand Down Expand Up @@ -164,6 +165,8 @@ class MapObjectSideBand
int16_t bouncecnt;
int16_t bounce;

uint16_t blood;

void(*logic)(MapObject&, GameLogic*);
void(*oldlogic)(MapObject&, GameLogic*);
void(*oldlogic2)(MapObject&, GameLogic*);
Expand Down
71 changes: 69 additions & 2 deletions monsterlogic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -485,8 +485,9 @@ void Shoot(MapObject& o, GameLogic* logic, int32_t colltype, int32_t collwith, i
newobject.data.ms.rad = 32;
newobject.data.ms.radsq = 32 * 32;


logic->AddObject(newobject);
newobject.data.ms.blood = 0;

logic->AddObject(newobject, true);
}

void TerraLogic2(MapObject& o, GameLogic* logic)
Expand Down Expand Up @@ -983,6 +984,7 @@ void BlowChunx(MapObject& thisobj, MapObject& otherobj, GameLogic* logic)
//chunks.data.ms.shape = scale;
chunks.data.ms.rad = logic->objectgraphics->maxwidthsgore[thisobj.t];
chunks.data.ms.radsq = chunks.data.ms.rad*chunks.data.ms.rad;
chunks.data.ms.blood = 0;

logic->newobjects.push_back(chunks);
}
Expand Down Expand Up @@ -1159,4 +1161,69 @@ void BaldyLogic(MapObject& o, GameLogic* logic)
}

BL2(o, logic);
}

void LizardLogic(MapObject& o, GameLogic* logic)
{
/*
lizardlogic ;
subq #1,ob_delay(a5)
bgt monstermove ;charge?
;
bsr pickcalc ;pic player in a0!
move ob_x(a5),d0
sub ob_x(a0),d0
muls d0,d0
move ob_z(a5),d1
sub ob_z(a0),d1
muls d1,d1
add.l d1,d0
cmp.l #256*256,d0
bcc.s bl2
;
move.l lizsfx(pc),a0
moveq #32,d0
moveq #5,d1
bsr playsfx
;
bra bl2
*/
o.data.ms.delay--;

if (o.data.ms.delay>0)
{
MonsterMove(o, logic);
return;
}

uint8_t ang = logic->PickCalc(o);

MapObject player = logic->GetPlayerObj();

int16_t dx = o.x.GetFrac() - player.x.GetFrac();
int16_t dz = o.z.GetFrac() - player.z.GetFrac();

int32_t res = (int32_t)dx * (int32_t)dx + (int32_t)dz * (int32_t)dz;

if (res < (256 * 256))
{
SoundHandler::Play(SoundHandler::SOUND_LIZARD);
}

BL2(o, logic);
}

void LizHurt(MapObject& thisobj, MapObject& otherobj, GameLogic* logic)
{
/*
lizhurt move.l a0,-(a7)
move.l lizhitsfx(pc),a0
moveq #64,d0
moveq #1,d1
bsr playsfx
move.l (a7)+,a0
bra hurtobject
*/
SoundHandler::Play(SoundHandler::SOUND_LIZHIT);
HurtObject(thisobj, otherobj, logic);
}
2 changes: 2 additions & 0 deletions monsterlogic.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,7 @@ void BlowObjectNoChunks(MapObject& thisobj, MapObject& otherobj, GameLogic* logi
void HurtTerra(MapObject& thisobj, MapObject& otherobj, GameLogic* logic);
void BlowTerra(MapObject& thisobj, MapObject& otherobj, GameLogic* logic);
void BaldyLogic(MapObject& o, GameLogic* logic);
void LizardLogic(MapObject& o, GameLogic* logic);
void LizHurt(MapObject& thisobj, MapObject& otherobj, GameLogic* logic);

void Shoot(MapObject& o, GameLogic* logic, int32_t colltype, int32_t collwith, int32_t hitpoints, int32_t damage, int32_t speed, std::vector<Shape>* shape);
Loading

0 comments on commit 5d1aa64

Please sign in to comment.