Implement SectorHeightChange notifications so IPU can render doors opening and closing and moving platforms etc correctly.

This commit is contained in:
jndean
2023-12-09 23:52:39 +00:00
parent 4a60f62a99
commit 5b57a6f924
10 changed files with 85 additions and 12 deletions
+10 -5
View File
@@ -1,12 +1,14 @@
![IPUDOOM](README_imgs/IPUDOOM.png)
A WIP to run Doom 1993 into the SRAM (~L1 cache) of the Graphcore MkII IPU (an AI accelerator chip which was definitely not designed to play video games). This is a hobby project, not a Graphcore product.
A WIP to run Doom 1993 in the SRAM (~L1 cache) of the Graphcore MkII IPU (an AI accelerator chip which was definitely not designed to play video games). This is a hobby project, not a Graphcore product.
## Build and Run
I use Ubuntu20 and Poplar SDK 3.3, but recent versions of either should be fine.
Due to the use of mutable global state and a custom exchange compiler, IPUDOOM requires a real IPU and will not run on the IPUModel (CPU simulating an IPU).
Make sure you have X11 fowarding over SSH working (use `ssh -X <address>` and have a local X server, e.g. Quartz on Mac, Xming on Windows). If your connection is fast enough, you should be able to get > 30 fps.
Make sure you have X11 fowarding over SSH working (use `ssh -X <address>` and have a local X server, e.g. Quartz on Mac, Xming on Windows). If your connection is fast enough, you should be able to get ~30 fps.
```bash
# Install dependencies
@@ -24,7 +26,7 @@ make -j4
# Download the doom shareware resource pack (contains the free levels)
wget https://distro.ibiblio.org/slitaz/sources/packages/d/doom1.wad
# To play the game, run. Press any key to bring up the menu.
# Run the game. It will start a demo - press any key to bring up the main menu.
./build/doom -iwad doom1.wad -width 320 -nosound -nomouse
```
@@ -60,15 +62,18 @@ Started with Chocolate Doom running on the CPU, began offloading subsystems to t
![Gameplay with textured and shaded floors and ceilings](README_imgs/TexturedFlats_noCPU.gif)
- [x] Implemented a (temporary?) system to notify IPU of map state changes, so that doors open and close properly and elevators work etc.
![GIF of a door closing and opening](README_imgs/DoorsMoving_noCPU.gif)
Immediate next steps:
- [ ] Implement temporary(?) system to notify IPU of map state changes, so that doors open and close properly. Perhaps the same could work for enemys and projectiles.
- [ ] Implement vissprite system and masked col rendering to add objects / enemies to levels.
- [ ] Set up the animation indirection tables so that animated texures work
Longer term next steps:
- [ ] Render HUD (probably easy using dedicated HUD-rendering tiles)
- [ ] Move beyond just the rendering?
- [ ] Move beyond just the rendering, i.e., have the IPU update its internal game state by itself rather than being told about changes by the CPU. Compared to rendering this might be reasonably cheap (in RAM), so may be able to exist entirely within the spare space on the render tiles? We shall see...
...
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

+2
View File
@@ -458,6 +458,8 @@ boolean D_InitNetGame(net_connect_data_t *connect_data)
if (M_CheckParm("-server") > 0
|| M_CheckParm("-privateserver") > 0)
{
printf("JOSEF SAYS: I do not support multiplayer :)\n");
exit(0); // But if you remove this return statement it might just work :)
NET_SV_Init();
NET_SV_AddModule(&net_loop_server_module);
NET_SV_AddModule(&net_sdl_module);
+1 -1
View File
@@ -145,7 +145,7 @@ void D_ProcessEvents(void) {
if (ev_buf.num_ev < IPUMAXEVENTSPERTIC) {
ev_buf.events[ev_buf.num_ev++] = *ev;
} else {
printf("WARNING: exceeding %d events per tic, keypresses may be dropped\n", IPUMAXEVENTSPERTIC);
printf("LAG SPIKE WARNING: exceeded %d events per tic, keypresses will be dropped\n", IPUMAXEVENTSPERTIC);
}
}
+7
View File
@@ -18,6 +18,7 @@ extern "C" {
#define IPUMAXEVENTSPERTIC (5)
#define IPUAMMARKBUFSIZE (544)
#define IPUMAPPEDLINEUPDATES (2)
#define IPUSECTORHEIGHTUPDATES (4)
#define IPUPROGBUFSIZE (128)
@@ -59,12 +60,18 @@ typedef struct {
int fixedcolormap;
} IPUTransfer_playerstate_t;
typedef struct {
fixed_t ceilingheight, floorheight;
int sectornum;
} IPUSectorHeightUpdate_t;
typedef struct {
int consoleplayer;
gamestate_t gamestate;
IPUTransfer_playerstate_t player;
int mappedline_updates[IPUMAPPEDLINEUPDATES];
IPUSectorHeightUpdate_t sectorheight_updates[IPUSECTORHEIGHTUPDATES];
} G_Ticker_MiscValues_t;
typedef struct {
+8 -2
View File
@@ -53,8 +53,14 @@ void IPU_G_Ticker_UnpackMiscValues(G_Ticker_MiscValues_t* pack) {
if (update == -1) break;
lines[update].flags |= ML_MAPPED;
}
for (int i = 0; i < IPUSECTORHEIGHTUPDATES; ++i) {
int sectornum = pack->sectorheight_updates[i].sectornum;
if (sectornum == -1) break;
sector_t *sector = &sectors[sectornum];
sector->ceilingheight = pack->sectorheight_updates[i].ceilingheight;
sector->floorheight = pack->sectorheight_updates[i].floorheight;
}
}
__SUPER__
+37 -2
View File
@@ -47,7 +47,7 @@ void IPU_G_LoadLevel_PackMiscValues(void* buf) {
}
#define MAX_BUFFERED_MAPPED_LINES 1000
#define MAX_BUFFERED_MAPPED_LINES (1000)
static int mapped_line_buf[MAX_BUFFERED_MAPPED_LINES];
static int mapped_line_count = 0;
@@ -67,6 +67,33 @@ void IPU_CheckAlreadyMappedLines(void) {
}
}
#define MAX_BUFFERED_SECTOR_HEIGHT_CHANGES (300)
static IPUSectorHeightUpdate_t sector_height_updates[MAX_BUFFERED_SECTOR_HEIGHT_CHANGES];
static int sector_height_update_count = 0;
void IPU_NotifySectorHeightChanged(sector_t *sector) {
if (sector_height_update_count == MAX_BUFFERED_SECTOR_HEIGHT_CHANGES) {
I_Error("\nERROR: sector_height_updates buffer is overflowing, dropping updates\n");
return;
}
int sectornum = sector - sectors;
int updateidx = sector_height_update_count;
for (int i = 0; i < sector_height_update_count; ++i) {
if (sector_height_updates[i].sectornum == sectornum) {
updateidx = i;
break;
}
}
sector_height_updates[updateidx].sectornum = sectornum;
sector_height_updates[updateidx].ceilingheight = sector->ceilingheight;
sector_height_updates[updateidx].floorheight = sector->floorheight;
if (updateidx == sector_height_update_count) {
sector_height_update_count++;
}
}
void IPU_G_Ticker_PackMiscValues(void* buf) {
assert(sizeof(G_Ticker_MiscValues_t) <= IPUMISCVALUESSIZE);
@@ -92,6 +119,14 @@ void IPU_G_Ticker_PackMiscValues(void* buf) {
}
pack->mappedline_updates[i] = mapped_line_buf[--mapped_line_count];
}
for (int i = 0; i < IPUSECTORHEIGHTUPDATES; ++i) {
if (!sector_height_update_count) {
pack->sectorheight_updates[i].sectornum = -1;
break;
}
pack->sectorheight_updates[i] = sector_height_updates[--sector_height_update_count];
}
}
void IPU_G_Responder_PackMiscValues(void* src_buf, void* dst_buf) {
@@ -169,4 +204,4 @@ void IPU_LoadSectorPicNums(byte* buf, int maxSize) {
data[2 * i] = sectors[i].floorpic;
data[2 * i + 1] = sectors[i].ceilingpic;
}
}
}
+1
View File
@@ -26,6 +26,7 @@ void IPU_LoadSectorPicNums(byte* buf, int maxSize);
void IPU_Setup_PackMarkNums(void* buf);
void IPU_NotifyLineMapped(line_t *line);
void IPU_CheckAlreadyMappedLines(void);
void IPU_NotifySectorHeightChanged(sector_t *sector);
+16 -2
View File
@@ -34,6 +34,8 @@
#include "sounds.h"
#include "z_zone.h"
#include "ipu_transfer.h"
//
// FLOORS
//
@@ -41,8 +43,11 @@
//
// Move a plane (floor or ceiling) and check for crushing
//
result_e T_MovePlane(sector_t *sector, fixed_t speed, fixed_t dest,
boolean crush, int floorOrCeiling, int direction) {
// JOSEF: Wrap T_MovePlane in a wrapper that notifies IPU of changes, and
// rename T_MovePlan as T_MovePlane_impl
result_e T_MovePlane_impl(sector_t *sector, fixed_t speed, fixed_t dest,
boolean crush, int floorOrCeiling, int direction) {
boolean flag;
fixed_t lastpos;
@@ -168,6 +173,15 @@ result_e T_MovePlane(sector_t *sector, fixed_t speed, fixed_t dest,
return ok;
}
// JOSEF: IPU-notifying wrapper
result_e T_MovePlane(sector_t *sector, fixed_t speed, fixed_t dest,
boolean crush, int floorOrCeiling, int direction) {
result_e result = T_MovePlane_impl(sector, speed, dest, crush, floorOrCeiling, direction);
IPU_NotifySectorHeightChanged(sector);
return result;
}
//
// MOVE A FLOOR TO IT'S DESTINATION (UP OR DOWN)
//
+3
View File
@@ -43,6 +43,8 @@
#include "r_state.h"
#include "z_zone.h"
#include "ipu_transfer.h"
FILE *save_stream;
int savegamelength;
boolean savegame_error;
@@ -1453,6 +1455,7 @@ void P_UnArchiveWorld(void) {
sec->tag = saveg_read16(); // needed?
sec->specialdata = 0;
sec->soundtarget = 0;
IPU_NotifySectorHeightChanged(sec);
}
// do lines