Add P_LoadNodes and refactor P_SetupLevel vertices to call via pointers. Add the stub for R_RenderPLayerView and transfering misc values (player and player->mobj). Start adding P_LoadThings, just aiming to get player mobj created during level load

This commit is contained in:
jndean
2023-08-22 17:18:44 +00:00
parent a5c1858937
commit 847882cc1d
18 changed files with 1503 additions and 176 deletions

View File

@@ -1,5 +1,5 @@
# SETUP
# apt-get install libsdl2-dev libsdl2-image-dev libsdl2-mixer-dev libsdl2-net-dev libpng-dev g++-7
# sudo apt update; sudo apt-get install -y libsdl2-dev libsdl2-image-dev libsdl2-mixer-dev libsdl2-net-dev libpng-dev g++-7
CPU_OBJ = $(addprefix build/cpu_obj/, ipu_host.o ipu_transfer.o i_system.o d_mode.o i_main.o m_argv.o m_misc.o net_common.o net_dedicated.o net_io.o net_packet.o net_query.o net_sdl.o net_server.o net_structrw.o aes_prng.o d_event.o d_iwad.o d_loop.o gusconf.o i_cdmus.o i_input.o i_joystick.o i_sdlmusic.o i_sdlsound.o i_sound.o i_timer.o i_video.o i_videohr.o midifile.o mus2mid.o m_bbox.o m_cheat.o m_config.o m_controls.o m_fixed.o net_client.o sha1.o memio.o tables.o v_video.o w_checksum.o w_main.o w_wad.o w_file.o w_file_stdc.o w_file_posix.o w_merge.o z_zone.o net_loop.o am_map.o d_items.o d_main.o d_net.o doomdef.o doomstat.o dstrings.o f_wipe.o g_game.o hu_lib.o hu_stuff.o info.o m_menu.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_maputl.o p_mobj.o p_plats.o p_pspr.o p_saveg.o p_setup.o p_sight.o p_spec.o p_switch.o p_telept.o p_tick.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 statdump.o wi_stuff.o)
@@ -17,6 +17,9 @@ IPU_OBJ = $(addprefix build/ipu_obj/, \
p_setup.gp \
p_setup_codelets.gp \
p_tick.gp \
r_bsp.gp \
r_codelets.gp \
r_main.gp \
tables.gp \
v_video.gp \
)

View File

@@ -4,6 +4,17 @@
A WIP to put Doom 1993 on the IPU.
```
# Install dependencies
sudo apt update; sudo apt-get install -y libsdl2-dev libsdl2-image-dev libsdl2-mixer-dev libsdl2-net-dev libpng-dev g++-7
# Build binary
make
# Download shareware resource pack
wget https://distro.ibiblio.org/slitaz/sources/packages/d/doom1.wad
# Run
./build/doom -iwad doom1.wad -width 320 -nosound
```
Activity Log:

View File

@@ -223,7 +223,7 @@ static fixed_t scale_mtof = (fixed_t)INITSCALEMTOF;
static fixed_t scale_ftom;
// JOSEF: Map only uses player position, so don't need reference to full
// player object (which will be on a different IPU tile).
// player object
// May need mechanism for sending plr->message to rendering tile... LATER
// static player_t *plr; // the player represented by an arrow
IPUPlayerPos_t am_playerpos;

View File

@@ -5,6 +5,7 @@ extern "C" {
#endif
#include "d_event.h"
#include "d_player.h"
#include "doomdef.h"
#include "doomtype.h"
#include "m_fixed.h"
@@ -43,6 +44,12 @@ typedef struct {
// Other things for responder here
} G_Responder_MiscValues_t;
typedef struct {
int displayplayer;
player_t players_displayplayer;
mobj_t displayplayer_mo;
} R_RenderPlayerView_MiscValues_t;
#ifdef __cplusplus

View File

@@ -40,26 +40,9 @@ void IPU_Setup_UnpackMarkNums(const unsigned char* buf) {
}
}
/*
void IPU_UnpackVertexes(const unsigned char* buf) {
IpuPackedLevel_t* pack = (IpuPackedLevel_t*) buf;
uint32_t pos = 0;
numvertexes = *(uint32_t*)buf;
mapvertex_t* ml = (mapvertex_t*)(&buf[4]);
vertex_t *li not done here;
for (int i = 0; i < numvertex)
vertexes = (vertex_t*) &pack->data[pos];
pos += numvertexes * sizeof(vertex_t);
numlines = pack->numlines;
lines = (line_t*) &pack->data[pos];
pos += numlines * sizeof(line_t);
// for (int i=0; i <)
// LATER: repoint other contents of lines
}
*/
void IPU_R_RenderPlayerView_UnpackMiscValues(R_RenderPlayerView_MiscValues_t* pack) {
displayplayer = pack->displayplayer;
players[displayplayer] = pack->players_displayplayer;
// TODO: pack->displaypayer_mo
}

View File

@@ -16,6 +16,7 @@ extern unsigned char markbuf[IPUAMMARKBUFSIZE];
void IPU_G_LoadLevel_UnpackMiscValues(G_LoadLevel_MiscValues_t* pack);
void IPU_G_Ticker_UnpackMiscValues(G_Ticker_MiscValues_t* pack);
void IPU_R_RenderPlayerView_UnpackMiscValues(R_RenderPlayerView_MiscValues_t* pack);
#ifdef __cplusplus
}

View File

@@ -9,6 +9,7 @@
#include "ipu_malloc.h"
#include "ipu_transfer.h"
#include "ipu_print.h"
#include "print.h"
//
@@ -140,6 +141,91 @@ void P_LoadSectors(const unsigned char *buf) {
requestedlumpnum = gamelumpnum + ML_SIDEDEFS;
}
//
// P_LoadNodes
//
__attribute__((optnone)) // Workaround for https://graphcore.atlassian.net/browse/LLVM-330
void P_LoadNodes(const unsigned char *buf) {
int i;
int j;
int k;
mapnode_t *mn;
node_t *no;
int lumplen = ((int*)buf)[0];
numnodes = lumplen / sizeof(mapnode_t);
nodes = IPU_level_malloc(numnodes * sizeof(node_t));
memset(nodes, 0, numnodes * sizeof(node_t));
mn = (mapnode_t *)(&buf[sizeof(int)]);
no = nodes;
for (i = 0; i < numnodes; i++, no++, mn++) {
no->x = SHORT(mn->x) << FRACBITS;
no->y = SHORT(mn->y) << FRACBITS;
no->dx = SHORT(mn->dx) << FRACBITS;
no->dy = SHORT(mn->dy) << FRACBITS;
for (j = 0; j < 2; j++) {
no->children[j] = SHORT(mn->children[j]);
for (k = 0; k < 4; k++) {
no->bbox[j][k] = SHORT(mn->bbox[j][k]) << FRACBITS;
}
}
}
}
//
// P_LoadThings
//
void P_LoadThings(const unsigned char *buf) {
byte *data;
int i;
mapthing_t *mt;
mapthing_t spawnthing;
int numthings;
boolean spawn;
int lumplen = ((int*)buf)[0];
numthings = lumplen / sizeof(mapthing_t);
mt = (mapthing_t *)(&buf[sizeof(int)]);
for (i = 0; i < numthings; i++, mt++) {
spawn = true;
// Do not spawn cool, new monsters if !commercial
if (gamemode != commercial) {
switch (SHORT(mt->type)) {
case 68: // Arachnotron
case 64: // Archvile
case 88: // Boss Brain
case 89: // Boss Shooter
case 69: // Hell Knight
case 67: // Mancubus
case 71: // Pain Elemental
case 65: // Former Human Commando
case 66: // Revenant
case 84: // Wolf SS
spawn = false;
break;
}
}
if (spawn == false)
break;
// Do spawn all other stuff.
spawnthing.x = SHORT(mt->x);
spawnthing.y = SHORT(mt->y);
spawnthing.angle = SHORT(mt->angle);
spawnthing.type = SHORT(mt->type);
spawnthing.options = SHORT(mt->options);
// P_SpawnMapThing(&spawnthing); // TODO
}
}
//
// P_LoadSideDefs
//
@@ -167,7 +253,7 @@ void P_LoadSideDefs(const unsigned char *buf) {
sd->sector = &sectors[SHORT(msd->sector)];
}
requestedlumpnum = gamelumpnum + ML_LINEDEFS;
requestedlumpnum = gamelumpnum + ML_LINEDEFS; // JOSEF: Get rid of this
}
//
@@ -238,18 +324,6 @@ void P_LoadLineDefs(const unsigned char *buf) {
else
ld->backsector = 0;
}
// msd = (mapsidedef_t *)(&buf[sizeof(int)]);
ipuprint("numlines: ");
ipuprintnum(numlines);
ipuprint(", sidenum0: ");
ipuprintnum(lines[0].sidenum[1]);
ipuprint(", sidenum-1: ");
ipuprintnum(lines[numlines-1].sidenum[1]);
ipuprint(", dx-1: ");
ipuprintnum(lines[numlines-1].dx);
ipuprint("\n");
requestedlumpnum = gamelumpnum + ML_SSECTORS;
}
@@ -281,7 +355,7 @@ void P_LoadSubsectors(const unsigned char *buf) {
//
// P_SetupLevel
//
void P_SetupLevel_pt0(void) {
void P_SetupLevel_pt0(const unsigned char unused) {
int i;
/* LATER

View File

@@ -1,99 +1,66 @@
#include <Vertex.hpp>
#include <print.h>
#include "doomdata.h"
#include "ipu_transfer.h"
extern "C" {
void P_SetupLevel_pt0(void);
void P_SetupLevel_pt0(const unsigned char *buf);
void P_LoadBlockMap(const unsigned char *buf);
void P_LoadVertexes(const unsigned char *buf);
void P_LoadSectors(const unsigned char *buf);
void P_LoadSideDefs(const unsigned char *buf);
void P_LoadLineDefs(const unsigned char *buf);
void P_LoadSubsectors(const unsigned char *buf);
void P_LoadNodes(const unsigned char *buf);
void P_LoadThings(const unsigned char *buf);
void IPU_Setup_UnpackMarkNums(const unsigned char* buf);
};
// --------------- P_Setup ----------------- //
class P_SetupLevel_pt0_Vertex : public poplar::Vertex {
poplar::Output<int> lumpNum;
public:
bool compute() {
P_SetupLevel_pt0();
*lumpNum = requestedlumpnum;
return true;
}
struct P_SetupLevel_SubFunc {
void (*func)(const unsigned char*);
int lump_num;
};
static P_SetupLevel_SubFunc setupLevelSubfuncs[14] = {
{P_SetupLevel_pt0, 0},
{P_LoadBlockMap, ML_BLOCKMAP},
{P_LoadVertexes, ML_VERTEXES},
{P_LoadSectors, ML_SECTORS},
{P_LoadSideDefs, ML_SIDEDEFS},
{P_LoadLineDefs, ML_LINEDEFS},
{P_LoadSubsectors, ML_SSECTORS},
{P_LoadNodes, ML_NODES},
// {P_LoadSegs, ML_SEGS},
// {P_GroupLines, ML_SEGS},
// {P_LoadReject, ML_REJECT},
{P_LoadThings, ML_THINGS},
// {P_SpawnSpecials, 0}
{NULL, 0}, /* SENTINEL */
};
class P_LoadBlockMap_Vertex : public poplar::Vertex {
// THIS IS CALLING VIA A POINTER. THAT'S PROBABLY BAD...
class P_SetupLevel_Vertex : public poplar::Vertex {
poplar::Input<poplar::Vector<unsigned char>> lumpBuf;
poplar::Output<int> lumpNum;
public:
bool compute() {
P_LoadBlockMap(&lumpBuf[0]);
*lumpNum = requestedlumpnum;
static int step = 0;
setupLevelSubfuncs[step].func(&lumpBuf[0]);
step += 1;
*lumpNum = gamelumpnum + setupLevelSubfuncs[step].lump_num;
if (setupLevelSubfuncs[step].func == NULL) {
step = 0;
}
return true;
}
};
class P_LoadVertexes_Vertex : public poplar::Vertex {
poplar::Input<poplar::Vector<unsigned char>> lumpBuf;
poplar::Output<int> lumpNum;
public:
bool compute() {
P_LoadVertexes(&lumpBuf[0]);
*lumpNum = requestedlumpnum;
return true;
}
};
class P_LoadSectors_Vertex : public poplar::Vertex {
poplar::Input<poplar::Vector<unsigned char>> lumpBuf;
poplar::Output<int> lumpNum;
public:
bool compute() {
P_LoadSectors(&lumpBuf[0]);
*lumpNum = requestedlumpnum;
return true;
}
};
class P_LoadSideDefs_Vertex : public poplar::Vertex {
poplar::Input<poplar::Vector<unsigned char>> lumpBuf;
poplar::Output<int> lumpNum;
public:
bool compute() {
P_LoadSideDefs(&lumpBuf[0]);
*lumpNum = requestedlumpnum;
return true;
}
};
class P_LoadLineDefs_Vertex : public poplar::Vertex {
poplar::Input<poplar::Vector<unsigned char>> lumpBuf;
poplar::Output<int> lumpNum;
public:
bool compute() {
P_LoadLineDefs(&lumpBuf[0]);
*lumpNum = requestedlumpnum;
return true;
}
};
class P_LoadSubsectors_Vertex : public poplar::Vertex {
poplar::Input<poplar::Vector<unsigned char>> lumpBuf;
poplar::Output<int> lumpNum;
public:
bool compute() {
P_LoadSubsectors(&lumpBuf[0]);
*lumpNum = requestedlumpnum;
return true;
}
};
// ------------ IPU_Setup ------------ //

497
src/ipu/r_bsp.c Normal file
View File

@@ -0,0 +1,497 @@
//
// Copyright(C) 1993-1996 Id Software, Inc.
// Copyright(C) 2005-2014 Simon Howard
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// DESCRIPTION:
// BSP traversal, handling of LineSegs for rendering.
//
#include <stddef.h>
#include "doomdata.h"
// State.
#include "doomstat.h"
#include "doomtype.h"
#include "i_system.h"
#include "i_video.h"
#include "m_bbox.h"
#include "m_fixed.h"
#include "r_defs.h"
#include "r_main.h"
#include "r_plane.h"
#include "r_state.h"
#include "r_things.h"
#include "tables.h"
//#include "r_local.h"
seg_t *curline;
side_t *sidedef;
line_t *linedef;
sector_t *frontsector;
sector_t *backsector;
drawseg_t drawsegs[MAXDRAWSEGS];
drawseg_t *ds_p;
void R_StoreWallRange(int start, int stop);
//
// R_ClearDrawSegs
//
void R_ClearDrawSegs(void) { ds_p = drawsegs; }
//
// ClipWallSegment
// Clips the given range of columns
// and includes it in the new clip list.
//
typedef struct {
int first;
int last;
} cliprange_t;
// We must expand MAXSEGS to the theoretical limit of the number of solidsegs
// that can be generated in a scene by the DOOM engine. This was determined by
// Lee Killough during BOOM development to be a function of the screensize.
// The simplest thing we can do, other than fix this bug, is to let the game
// render overage and then bomb out by detecting the overflow after the
// fact. -haleyjd
//#define MAXSEGS 32
#define MAXSEGS (SCREENWIDTH / 2 + 1)
// newend is one past the last valid seg
cliprange_t *newend;
cliprange_t solidsegs[MAXSEGS];
//
// R_ClipSolidWallSegment
// Does handle solid walls,
// e.g. single sided LineDefs (middle texture)
// that entirely block the view.
//
void R_ClipSolidWallSegment(int first, int last) {
cliprange_t *next;
cliprange_t *start;
// Find the first range that touches the range
// (adjacent pixels are touching).
start = solidsegs;
while (start->last < first - 1)
start++;
if (first < start->first) {
if (last < start->first - 1) {
// Post is entirely visible (above start),
// so insert a new clippost.
R_StoreWallRange(first, last);
next = newend;
newend++;
while (next != start) {
*next = *(next - 1);
next--;
}
next->first = first;
next->last = last;
return;
}
// There is a fragment above *start.
R_StoreWallRange(first, start->first - 1);
// Now adjust the clip size.
start->first = first;
}
// Bottom contained in start?
if (last <= start->last)
return;
next = start;
while (last >= (next + 1)->first - 1) {
// There is a fragment between two posts.
R_StoreWallRange(next->last + 1, (next + 1)->first - 1);
next++;
if (last <= next->last) {
// Bottom is contained in next.
// Adjust the clip size.
start->last = next->last;
goto crunch;
}
}
// There is a fragment after *next.
R_StoreWallRange(next->last + 1, last);
// Adjust the clip size.
start->last = last;
// Remove start+1 to next from the clip list,
// because start now covers their area.
crunch:
if (next == start) {
// Post just extended past the bottom of one post.
return;
}
while (next++ != newend) {
// Remove a post.
*++start = *next;
}
newend = start + 1;
}
//
// R_ClipPassWallSegment
// Clips the given range of columns,
// but does not includes it in the clip list.
// Does handle windows,
// e.g. LineDefs with upper and lower texture.
//
void R_ClipPassWallSegment(int first, int last) {
cliprange_t *start;
// Find the first range that touches the range
// (adjacent pixels are touching).
start = solidsegs;
while (start->last < first - 1)
start++;
if (first < start->first) {
if (last < start->first - 1) {
// Post is entirely visible (above start).
R_StoreWallRange(first, last);
return;
}
// There is a fragment above *start.
R_StoreWallRange(first, start->first - 1);
}
// Bottom contained in start?
if (last <= start->last)
return;
while (last >= (start + 1)->first - 1) {
// There is a fragment between two posts.
R_StoreWallRange(start->last + 1, (start + 1)->first - 1);
start++;
if (last <= start->last)
return;
}
// There is a fragment after *next.
R_StoreWallRange(start->last + 1, last);
}
//
// R_ClearClipSegs
//
void R_ClearClipSegs(void) {
solidsegs[0].first = -0x7fffffff;
solidsegs[0].last = -1;
solidsegs[1].first = viewwidth;
solidsegs[1].last = 0x7fffffff;
newend = solidsegs + 2;
}
//
// R_AddLine
// Clips the given segment
// and adds any visible pieces to the line list.
//
void R_AddLine(seg_t *line) {
int x1;
int x2;
angle_t angle1;
angle_t angle2;
angle_t span;
angle_t tspan;
curline = line;
// OPTIMIZE: quickly reject orthogonal back sides.
angle1 = R_PointToAngle(line->v1->x, line->v1->y);
angle2 = R_PointToAngle(line->v2->x, line->v2->y);
// Clip to view edges.
// OPTIMIZE: make constant out of 2*clipangle (FIELDOFVIEW).
span = angle1 - angle2;
// Back side? I.e. backface culling?
if (span >= ANG180)
return;
// Global angle needed by segcalc.
rw_angle1 = angle1;
angle1 -= viewangle;
angle2 -= viewangle;
tspan = angle1 + clipangle;
if (tspan > 2 * clipangle) {
tspan -= 2 * clipangle;
// Totally off the left edge?
if (tspan >= span)
return;
angle1 = clipangle;
}
tspan = clipangle - angle2;
if (tspan > 2 * clipangle) {
tspan -= 2 * clipangle;
// Totally off the left edge?
if (tspan >= span)
return;
angle2 = -clipangle;
}
// The seg is in the view range,
// but not necessarily visible.
angle1 = (angle1 + ANG90) >> ANGLETOFINESHIFT;
angle2 = (angle2 + ANG90) >> ANGLETOFINESHIFT;
x1 = viewangletox[angle1];
x2 = viewangletox[angle2];
// Does not cross a pixel?
if (x1 == x2)
return;
backsector = line->backsector;
// Single sided line?
if (!backsector)
goto clipsolid;
// Closed door.
if (backsector->ceilingheight <= frontsector->floorheight ||
backsector->floorheight >= frontsector->ceilingheight)
goto clipsolid;
// Window.
if (backsector->ceilingheight != frontsector->ceilingheight ||
backsector->floorheight != frontsector->floorheight)
goto clippass;
// Reject empty lines used for triggers
// and special events.
// Identical floor and ceiling on both sides,
// identical light levels on both sides,
// and no middle texture.
if (backsector->ceilingpic == frontsector->ceilingpic &&
backsector->floorpic == frontsector->floorpic &&
backsector->lightlevel == frontsector->lightlevel &&
curline->sidedef->midtexture == 0) {
return;
}
clippass:
R_ClipPassWallSegment(x1, x2 - 1);
return;
clipsolid:
R_ClipSolidWallSegment(x1, x2 - 1);
}
//
// R_CheckBBox
// Checks BSP node/subtree bounding box.
// Returns true
// if some part of the bbox might be visible.
//
int checkcoord[12][4] = {{3, 0, 2, 1}, {3, 0, 2, 0}, {3, 1, 2, 0}, {0},
{2, 0, 2, 1}, {0, 0, 0, 0}, {3, 1, 3, 0}, {0},
{2, 0, 3, 1}, {2, 1, 3, 1}, {2, 1, 3, 0}};
boolean R_CheckBBox(fixed_t *bspcoord) {
int boxx;
int boxy;
int boxpos;
fixed_t x1;
fixed_t y1;
fixed_t x2;
fixed_t y2;
angle_t angle1;
angle_t angle2;
angle_t span;
angle_t tspan;
cliprange_t *start;
int sx1;
int sx2;
// Find the corners of the box
// that define the edges from current viewpoint.
if (viewx <= bspcoord[BOXLEFT])
boxx = 0;
else if (viewx < bspcoord[BOXRIGHT])
boxx = 1;
else
boxx = 2;
if (viewy >= bspcoord[BOXTOP])
boxy = 0;
else if (viewy > bspcoord[BOXBOTTOM])
boxy = 1;
else
boxy = 2;
boxpos = (boxy << 2) + boxx;
if (boxpos == 5)
return true;
x1 = bspcoord[checkcoord[boxpos][0]];
y1 = bspcoord[checkcoord[boxpos][1]];
x2 = bspcoord[checkcoord[boxpos][2]];
y2 = bspcoord[checkcoord[boxpos][3]];
// check clip list for an open space
angle1 = R_PointToAngle(x1, y1) - viewangle;
angle2 = R_PointToAngle(x2, y2) - viewangle;
span = angle1 - angle2;
// Sitting on a line?
if (span >= ANG180)
return true;
tspan = angle1 + clipangle;
if (tspan > 2 * clipangle) {
tspan -= 2 * clipangle;
// Totally off the left edge?
if (tspan >= span)
return false;
angle1 = clipangle;
}
tspan = clipangle - angle2;
if (tspan > 2 * clipangle) {
tspan -= 2 * clipangle;
// Totally off the left edge?
if (tspan >= span)
return false;
angle2 = -clipangle;
}
// Find the first clippost
// that touches the source post
// (adjacent pixels are touching).
angle1 = (angle1 + ANG90) >> ANGLETOFINESHIFT;
angle2 = (angle2 + ANG90) >> ANGLETOFINESHIFT;
sx1 = viewangletox[angle1];
sx2 = viewangletox[angle2];
// Does not cross a pixel.
if (sx1 == sx2)
return false;
sx2--;
start = solidsegs;
while (start->last < sx2)
start++;
if (sx1 >= start->first && sx2 <= start->last) {
// The clippost contains the new span.
return false;
}
return true;
}
//
// R_Subsector
// Determine floor/ceiling planes.
// Add sprites of things in sector.
// Draw one or more line segments.
//
void R_Subsector(int num) {
int count;
seg_t *line;
subsector_t *sub;
if (num >= numsubsectors)
I_Error("R_Subsector: ss %i with numss = %i", num, numsubsectors);
sscount++;
sub = &subsectors[num];
frontsector = sub->sector;
count = sub->numlines;
line = &segs[sub->firstline];
if (frontsector->floorheight < viewz) {
floorplane = R_FindPlane(frontsector->floorheight, frontsector->floorpic,
frontsector->lightlevel);
} else
floorplane = NULL;
if (frontsector->ceilingheight > viewz ||
frontsector->ceilingpic == skyflatnum) {
ceilingplane =
R_FindPlane(frontsector->ceilingheight, frontsector->ceilingpic,
frontsector->lightlevel);
} else
ceilingplane = NULL;
R_AddSprites(frontsector);
while (count--) {
R_AddLine(line);
line++;
}
// check for solidsegs overflow - extremely unsatisfactory!
if (newend > &solidsegs[32])
I_Error("R_Subsector: solidsegs overflow (vanilla may crash here)\n");
}
//
// RenderBSPNode
// Renders all subsectors below a given node,
// traversing subtree recursively.
// Just call with BSP root.
void R_RenderBSPNode(int bspnum) {
node_t *bsp;
int side;
// Found a subsector?
if (bspnum & NF_SUBSECTOR) {
if (bspnum == -1)
R_Subsector(0);
else
R_Subsector(bspnum & (~NF_SUBSECTOR));
return;
}
bsp = &nodes[bspnum];
// Decide which side the view point is on.
side = R_PointOnSide(viewx, viewy, bsp);
// Recursively divide front space.
R_RenderBSPNode(bsp->children[side]);
// Possibly divide back space.
if (R_CheckBBox(bsp->bbox[side ^ 1]))
R_RenderBSPNode(bsp->children[side ^ 1]);
}

33
src/ipu/r_codelets.cpp Normal file
View File

@@ -0,0 +1,33 @@
#include <Vertex.hpp>
#include <print.h>
// #include "doomdata.h"
#include "ipu_transfer.h"
extern "C" {
// void P_SetupLevel_pt0(const unsigned char *buf);
};
// --------------- P_Setup ----------------- //
struct R_RenderPlayerView_Vertex : public poplar::Vertex {
poplar::Input<poplar::Vector<unsigned char>> miscValues;
poplar::InOut<poplar::Vector<unsigned char>> frame;
void compute() {
// printf("Running R_RenderPlayerView_Vertex\n");
// AM_Drawer(&frame[0]);
for (int i = 0; i < 100; ++i){
frame[i + 320 * i ] = 1;
frame[i + 320 * i + 1] = 1;
}
IPU_R_RenderPlayerView_UnpackMiscValues(
(R_RenderPlayerView_MiscValues_t*) &miscValues[0]
);
return ;
}
};

760
src/ipu/r_main.c Normal file
View File

@@ -0,0 +1,760 @@
//
// Copyright(C) 1993-1996 Id Software, Inc.
// Copyright(C) 2005-2014 Simon Howard
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// DESCRIPTION:
// Rendering main loop and setup functions,
// utility functions (BSP, geometry, trigonometry).
// See tables.c, too.
//
// #include <stdio.h> // JOSEF
// #include <stdlib.h>
#include "d_loop.h"
#include "d_player.h"
#include "doomdata.h"
#include "doomtype.h"
#include "i_video.h"
#include "m_bbox.h"
#include "m_fixed.h"
#include "m_menu.h"
#include "p_mobj.h"
#include "r_bsp.h"
#include "r_data.h"
#include "r_defs.h"
#include "r_draw.h"
#include "r_main.h"
#include "r_plane.h"
#include "r_sky.h"
#include "r_state.h"
#include "r_things.h"
#include "tables.h"
// JOSEF: added
inline int abs(int x) {
return (x < 0) ? -x : x;
}
// Fineangles in the SCREENWIDTH wide window.
#define FIELDOFVIEW 2048
int viewangleoffset;
// increment every time a check is made
int validcount = 1;
lighttable_t *fixedcolormap;
extern lighttable_t **walllights;
int centerx;
int centery;
fixed_t centerxfrac;
fixed_t centeryfrac;
fixed_t projection;
// just for profiling purposes
int framecount;
int sscount;
int linecount;
int loopcount;
fixed_t viewx;
fixed_t viewy;
fixed_t viewz;
angle_t viewangle;
fixed_t viewcos;
fixed_t viewsin;
player_t *viewplayer;
// 0 = high, 1 = low
int detailshift;
//
// precalculated math tables
//
angle_t clipangle;
// The viewangletox[viewangle + FINEANGLES/4] lookup
// maps the visible view angles to screen X coordinates,
// flattening the arc to a flat projection plane.
// There will be many angles mapped to the same X.
int viewangletox[FINEANGLES / 2];
// The xtoviewangleangle[] table maps a screen pixel
// to the lowest viewangle that maps back to x ranges
// from clipangle to -clipangle.
angle_t xtoviewangle[SCREENWIDTH + 1];
// lighttable_t *scalelight[LIGHTLEVELS][MAXLIGHTSCALE]; // JOSEF: TODO
// lighttable_t *scalelightfixed[MAXLIGHTSCALE]; // JOSEF: TODO
// lighttable_t *zlight[LIGHTLEVELS][MAXLIGHTZ]; // JOSEF: TODO
// bumped light from gun blasts
int extralight;
void (*colfunc)(void);
void (*basecolfunc)(void);
void (*fuzzcolfunc)(void);
void (*transcolfunc)(void);
void (*spanfunc)(void);
/*
//
// R_AddPointToBox
// Expand a given bbox
// so that it encloses a given point.
//
void R_AddPointToBox(int x, int y, fixed_t *box) {
if (x < box[BOXLEFT])
box[BOXLEFT] = x;
if (x > box[BOXRIGHT])
box[BOXRIGHT] = x;
if (y < box[BOXBOTTOM])
box[BOXBOTTOM] = y;
if (y > box[BOXTOP])
box[BOXTOP] = y;
}
//
// R_PointOnSide
// Traverse BSP (sub) tree,
// check point against partition plane.
// Returns side 0 (front) or 1 (back).
//
int R_PointOnSide(fixed_t x, fixed_t y, node_t *node) {
fixed_t dx;
fixed_t dy;
fixed_t left;
fixed_t right;
if (!node->dx) {
if (x <= node->x)
return node->dy > 0;
return node->dy < 0;
}
if (!node->dy) {
if (y <= node->y)
return node->dx < 0;
return node->dx > 0;
}
dx = (x - node->x);
dy = (y - node->y);
// Try to quickly decide by looking at sign bits.
if ((node->dy ^ node->dx ^ dx ^ dy) & 0x80000000) {
if ((node->dy ^ dx) & 0x80000000) {
// (left is negative)
return 1;
}
return 0;
}
left = FixedMul(node->dy >> FRACBITS, dx);
right = FixedMul(dy, node->dx >> FRACBITS);
if (right < left) {
// front side
return 0;
}
// back side
return 1;
}
int R_PointOnSegSide(fixed_t x, fixed_t y, seg_t *line) {
fixed_t lx;
fixed_t ly;
fixed_t ldx;
fixed_t ldy;
fixed_t dx;
fixed_t dy;
fixed_t left;
fixed_t right;
lx = line->v1->x;
ly = line->v1->y;
ldx = line->v2->x - lx;
ldy = line->v2->y - ly;
if (!ldx) {
if (x <= lx)
return ldy > 0;
return ldy < 0;
}
if (!ldy) {
if (y <= ly)
return ldx < 0;
return ldx > 0;
}
dx = (x - lx);
dy = (y - ly);
// Try to quickly decide by looking at sign bits.
if ((ldy ^ ldx ^ dx ^ dy) & 0x80000000) {
if ((ldy ^ dx) & 0x80000000) {
// (left is negative)
return 1;
}
return 0;
}
left = FixedMul(ldy >> FRACBITS, dx);
right = FixedMul(dy, ldx >> FRACBITS);
if (right < left) {
// front side
return 0;
}
// back side
return 1;
}
//
// R_PointToAngle
// To get a global angle from cartesian coordinates,
// the coordinates are flipped until they are in
// the first octant of the coordinate system, then
// the y (<=x) is scaled and divided by x to get a
// tangent (slope) value which is looked up in the
// tantoangle[] table.
//
angle_t R_PointToAngle(fixed_t x, fixed_t y) {
x -= viewx;
y -= viewy;
if ((!x) && (!y))
return 0;
if (x >= 0) {
// x >=0
if (y >= 0) {
// y>= 0
if (x > y) {
// octant 0
return tantoangle[SlopeDiv(y, x)];
} else {
// octant 1
return ANG90 - 1 - tantoangle[SlopeDiv(x, y)];
}
} else {
// y<0
y = -y;
if (x > y) {
// octant 8
return -tantoangle[SlopeDiv(y, x)];
} else {
// octant 7
return ANG270 + tantoangle[SlopeDiv(x, y)];
}
}
} else {
// x<0
x = -x;
if (y >= 0) {
// y>= 0
if (x > y) {
// octant 3
return ANG180 - 1 - tantoangle[SlopeDiv(y, x)];
} else {
// octant 2
return ANG90 + tantoangle[SlopeDiv(x, y)];
}
} else {
// y<0
y = -y;
if (x > y) {
// octant 4
return ANG180 + tantoangle[SlopeDiv(y, x)];
} else {
// octant 5
return ANG270 - 1 - tantoangle[SlopeDiv(x, y)];
}
}
}
return 0;
}
angle_t R_PointToAngle2(fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2) {
viewx = x1;
viewy = y1;
return R_PointToAngle(x2, y2);
}
fixed_t R_PointToDist(fixed_t x, fixed_t y) {
int angle;
fixed_t dx;
fixed_t dy;
fixed_t temp;
fixed_t dist;
fixed_t frac;
dx = abs(x - viewx);
dy = abs(y - viewy);
if (dy > dx) {
temp = dx;
dx = dy;
dy = temp;
}
// Fix crashes in udm1.wad
if (dx != 0) {
frac = FixedDiv(dy, dx);
} else {
frac = 0;
}
angle = (tantoangle[frac >> DBITS] + ANG90) >> ANGLETOFINESHIFT;
// use as cosine
dist = FixedDiv(dx, finesine[angle]);
return dist;
}
//
// R_InitPointToAngle
//
void R_InitPointToAngle(void) {
// UNUSED - now getting from tables.c
#if 0
int i;
long t;
float f;
//
// slope (tangent) to angle lookup
//
for (i=0 ; i<=SLOPERANGE ; i++)
{
f = atan( (float)i/SLOPERANGE )/(3.141592657*2);
t = 0xffffffff*f;
tantoangle[i] = t;
}
#endif
}
//
// R_ScaleFromGlobalAngle
// Returns the texture mapping scale
// for the current line (horizontal span)
// at the given angle.
// rw_distance must be calculated first.
//
fixed_t R_ScaleFromGlobalAngle(angle_t visangle) {
fixed_t scale;
angle_t anglea;
angle_t angleb;
int sinea;
int sineb;
fixed_t num;
int den;
// UNUSED
#if 0
{
fixed_t dist;
fixed_t z;
fixed_t sinv;
fixed_t cosv;
sinv = finesine[(visangle-rw_normalangle)>>ANGLETOFINESHIFT];
dist = FixedDiv (rw_distance, sinv);
cosv = finecosine[(viewangle-visangle)>>ANGLETOFINESHIFT];
z = abs(FixedMul (dist, cosv));
scale = FixedDiv(projection, z);
return scale;
}
#endif
anglea = ANG90 + (visangle - viewangle);
angleb = ANG90 + (visangle - rw_normalangle);
// both sines are allways positive
sinea = finesine[anglea >> ANGLETOFINESHIFT];
sineb = finesine[angleb >> ANGLETOFINESHIFT];
num = FixedMul(projection, sineb) << detailshift;
den = FixedMul(rw_distance, sinea);
if (den > num >> FRACBITS) {
scale = FixedDiv(num, den);
if (scale > 64 * FRACUNIT)
scale = 64 * FRACUNIT;
else if (scale < 256)
scale = 256;
} else
scale = 64 * FRACUNIT;
return scale;
}
//
// R_InitTables
//
void R_InitTables(void) {
// UNUSED: now getting from tables.c
#if 0
int i;
float a;
float fv;
int t;
// viewangle tangent table
for (i=0 ; i<FINEANGLES/2 ; i++)
{
a = (i-FINEANGLES/4+0.5)*PI*2/FINEANGLES;
fv = FRACUNIT*tan (a);
t = fv;
finetangent[i] = t;
}
// finesine table
for (i=0 ; i<5*FINEANGLES/4 ; i++)
{
// OPTIMIZE: mirror...
a = (i+0.5)*PI*2/FINEANGLES;
t = FRACUNIT*sin (a);
finesine[i] = t;
}
#endif
}
//
// R_InitTextureMapping
//
void R_InitTextureMapping(void) {
int i;
int x;
int t;
fixed_t focallength;
// Use tangent table to generate viewangletox:
// viewangletox will give the next greatest x
// after the view angle.
//
// Calc focallength
// so FIELDOFVIEW angles covers SCREENWIDTH.
focallength =
FixedDiv(centerxfrac, finetangent[FINEANGLES / 4 + FIELDOFVIEW / 2]);
for (i = 0; i < FINEANGLES / 2; i++) {
if (finetangent[i] > FRACUNIT * 2)
t = -1;
else if (finetangent[i] < -FRACUNIT * 2)
t = viewwidth + 1;
else {
t = FixedMul(finetangent[i], focallength);
t = (centerxfrac - t + FRACUNIT - 1) >> FRACBITS;
if (t < -1)
t = -1;
else if (t > viewwidth + 1)
t = viewwidth + 1;
}
viewangletox[i] = t;
}
// Scan viewangletox[] to generate xtoviewangle[]:
// xtoviewangle will give the smallest view angle
// that maps to x.
for (x = 0; x <= viewwidth; x++) {
i = 0;
while (viewangletox[i] > x)
i++;
xtoviewangle[x] = (i << ANGLETOFINESHIFT) - ANG90;
}
// Take out the fencepost cases from viewangletox.
for (i = 0; i < FINEANGLES / 2; i++) {
t = FixedMul(finetangent[i], focallength);
t = centerx - t;
if (viewangletox[i] == -1)
viewangletox[i] = 0;
else if (viewangletox[i] == viewwidth + 1)
viewangletox[i] = viewwidth;
}
clipangle = xtoviewangle[0];
}
//
// R_InitLightTables
// Only inits the zlight table,
// because the scalelight table changes with view size.
//
#define DISTMAP 2
void R_InitLightTables(void) {
int i;
int j;
int level;
int startmap;
int scale;
// Calculate the light levels to use
// for each level / distance combination.
for (i = 0; i < LIGHTLEVELS; i++) {
startmap = ((LIGHTLEVELS - 1 - i) * 2) * NUMCOLORMAPS / LIGHTLEVELS;
for (j = 0; j < MAXLIGHTZ; j++) {
scale = FixedDiv((SCREENWIDTH / 2 * FRACUNIT), (j + 1) << LIGHTZSHIFT);
scale >>= LIGHTSCALESHIFT;
level = startmap - scale / DISTMAP;
if (level < 0)
level = 0;
if (level >= NUMCOLORMAPS)
level = NUMCOLORMAPS - 1;
zlight[i][j] = colormaps + level * 256;
}
}
}
//
// R_SetViewSize
// Do not really change anything here,
// because it might be in the middle of a refresh.
// The change will take effect next refresh.
//
boolean setsizeneeded;
int setblocks;
int setdetail;
void R_SetViewSize(int blocks, int detail) {
setsizeneeded = true;
setblocks = blocks;
setdetail = detail;
}
//
// R_ExecuteSetViewSize
//
void R_ExecuteSetViewSize(void) {
fixed_t cosadj;
fixed_t dy;
int i;
int j;
int level;
int startmap;
setsizeneeded = false;
if (setblocks == 11) {
scaledviewwidth = SCREENWIDTH;
viewheight = SCREENHEIGHT;
} else {
scaledviewwidth = setblocks * 32;
viewheight = (setblocks * 168 / 10) & ~7;
}
detailshift = setdetail;
viewwidth = scaledviewwidth >> detailshift;
centery = viewheight / 2;
centerx = viewwidth / 2;
centerxfrac = centerx << FRACBITS;
centeryfrac = centery << FRACBITS;
projection = centerxfrac;
if (!detailshift) {
colfunc = basecolfunc = R_DrawColumn;
fuzzcolfunc = R_DrawFuzzColumn;
transcolfunc = R_DrawTranslatedColumn;
spanfunc = R_DrawSpan;
} else {
colfunc = basecolfunc = R_DrawColumnLow;
fuzzcolfunc = R_DrawFuzzColumnLow;
transcolfunc = R_DrawTranslatedColumnLow;
spanfunc = R_DrawSpanLow;
}
R_InitBuffer(scaledviewwidth, viewheight);
R_InitTextureMapping();
// psprite scales
pspritescale = FRACUNIT * viewwidth / SCREENWIDTH;
pspriteiscale = FRACUNIT * SCREENWIDTH / viewwidth;
// thing clipping
for (i = 0; i < viewwidth; i++)
screenheightarray[i] = viewheight;
// planes
for (i = 0; i < viewheight; i++) {
dy = ((i - viewheight / 2) << FRACBITS) + FRACUNIT / 2;
dy = abs(dy);
yslope[i] = FixedDiv((viewwidth << detailshift) / 2 * FRACUNIT, dy);
}
for (i = 0; i < viewwidth; i++) {
cosadj = abs(finecosine[xtoviewangle[i] >> ANGLETOFINESHIFT]);
distscale[i] = FixedDiv(FRACUNIT, cosadj);
}
// Calculate the light levels to use
// for each level / scale combination.
for (i = 0; i < LIGHTLEVELS; i++) {
startmap = ((LIGHTLEVELS - 1 - i) * 2) * NUMCOLORMAPS / LIGHTLEVELS;
for (j = 0; j < MAXLIGHTSCALE; j++) {
level = startmap - j * SCREENWIDTH / (viewwidth << detailshift) / DISTMAP;
if (level < 0)
level = 0;
if (level >= NUMCOLORMAPS)
level = NUMCOLORMAPS - 1;
scalelight[i][j] = colormaps + level * 256;
}
}
}
//
// R_Init
//
void R_Init(void) {
R_InitData();
// printf("."); // JOSEF
R_InitPointToAngle();
// printf("."); // JOSEF
R_InitTables();
// viewwidth / viewheight / detailLevel are set by the defaults
// printf("."); // JOSEF
R_SetViewSize(screenblocks, detailLevel);
R_InitPlanes();
// printf("."); // JOSEF
R_InitLightTables();
// printf("."); // JOSEF
R_InitSkyMap();
R_InitTranslationTables();
// printf("."); // JOSEF
framecount = 0;
}
//
// R_PointInSubsector
//
subsector_t *R_PointInSubsector(fixed_t x, fixed_t y) {
node_t *node;
int side;
int nodenum;
// single subsector is a special case
if (!numnodes)
return subsectors;
nodenum = numnodes - 1;
while (!(nodenum & NF_SUBSECTOR)) {
node = &nodes[nodenum];
side = R_PointOnSide(x, y, node);
nodenum = node->children[side];
}
return &subsectors[nodenum & ~NF_SUBSECTOR];
}
*/
//
// R_SetupFrame
//
void R_SetupFrame(player_t *player) {
int i;
viewplayer = player;
viewx = player->mo->x;
viewy = player->mo->y;
viewangle = player->mo->angle + viewangleoffset;
extralight = player->extralight;
viewz = player->viewz;
viewsin = finesine[viewangle >> ANGLETOFINESHIFT];
viewcos = finecosine[viewangle >> ANGLETOFINESHIFT];
sscount = 0;
if (player->fixedcolormap) {
fixedcolormap = colormaps + player->fixedcolormap * 256;
walllights = scalelightfixed;
for (i = 0; i < MAXLIGHTSCALE; i++)
scalelightfixed[i] = fixedcolormap;
} else
fixedcolormap = 0;
framecount++;
validcount++;
}
//
// R_RenderView
//
void R_RenderPlayerView(player_t *player) {
R_SetupFrame(player);
// Clear buffers.
// R_ClearClipSegs(); // TODO
// R_ClearDrawSegs(); // TODO
// R_ClearPlanes(); // TODO
// R_ClearSprites(); // TODO
// check for new console commands.
// NetUpdate(); // TODO
// The head node is the last node output.
// R_RenderBSPNode(numnodes - 1); // TODO
// Check for new console commands.
// NetUpdate(); // TODO
// R_DrawPlanes(); // TODO
// Check for new console commands.
// NetUpdate(); // TODO
// R_DrawMasked(); // TODO
// Check for new console commands.
// NetUpdate(); // TODO
}

View File

@@ -1,3 +1,6 @@
// Yes, I know this file is full of awful unnecessary boilerplate and interfaces, the
// structure of the IPU<->Host interface is evolving __somewhat organically__ ...
#include "ipu_host.h"
#include <algorithm>
@@ -39,6 +42,7 @@ class IpuDoom {
void buildIpuGraph();
void run_AM_Drawer();
void run_R_RenderPlayerView();
void run_IPU_Setup();
void run_G_DoLoadLevel();
void run_G_Ticker();
@@ -57,7 +61,7 @@ class IpuDoom {
};
IpuDoom::IpuDoom()
: m_ipuDevice(getIpu(false, 1)),
: m_ipuDevice(getIpu(true, 1)),
m_ipuGraph(/*poplar::Target::createIPUTarget(1, "ipu2")*/ m_ipuDevice.getTarget()),
m_ipuEngine(nullptr) {
buildIpuGraph();
@@ -67,7 +71,7 @@ IpuDoom::~IpuDoom(){};
void IpuDoom::buildIpuGraph() {
m_ipuGraph.addCodelets("build/ipu_rt.gp");
// -------- AM_Drawer_CS ------ //
// -------- GetPrintbuf_CS (helper) ------ //
poplar::Tensor printbuf =
m_ipuGraph.addVariable(poplar::CHAR, {(ulong)IPUPRINTBUFSIZE}, "ipuprint_buf");
@@ -80,7 +84,7 @@ void IpuDoom::buildIpuGraph() {
m_ipuGraph.setTileMapping(vtx, 0);
m_ipuGraph.setPerfEstimate(vtx, IPUPRINTBUFSIZE);
poplar::program::Sequence GetPrintbuf_prog({
poplar::program::Sequence GetPrintbuf_prog({
poplar::program::Execute(GetPrintbuf_CS),
poplar::program::Copy(printbuf, printbufOutStream),
});
@@ -125,69 +129,20 @@ void IpuDoom::buildIpuGraph() {
auto lumpNumStream = m_ipuGraph.addDeviceToHostFIFO("lumpNum-stream", poplar::INT, 1);
poplar::ComputeSet P_SetupLevel_CS = m_ipuGraph.addComputeSet("P_SetupLevel_CS");
vtx = m_ipuGraph.addVertex(P_SetupLevel_CS, "P_SetupLevel_pt0_Vertex", {{"lumpNum", m_lumpNum}});
m_ipuGraph.setTileMapping(vtx, 0);
m_ipuGraph.setPerfEstimate(vtx, 100);
poplar::ComputeSet P_LoadBlockMap_CS = m_ipuGraph.addComputeSet("P_LoadBlockMap_CS");
vtx = m_ipuGraph.addVertex(P_LoadBlockMap_CS, "P_LoadBlockMap_Vertex", {
vtx = m_ipuGraph.addVertex(P_SetupLevel_CS, "P_SetupLevel_Vertex", {
{"lumpNum", m_lumpNum}, {"lumpBuf", m_lumpBuf}});
m_ipuGraph.setTileMapping(vtx, 0);
m_ipuGraph.setPerfEstimate(vtx, 100);
poplar::ComputeSet P_LoadVertexes_CS = m_ipuGraph.addComputeSet("P_LoadVertexes_CS");
vtx = m_ipuGraph.addVertex(P_LoadVertexes_CS, "P_LoadVertexes_Vertex", {
{"lumpNum", m_lumpNum}, {"lumpBuf", m_lumpBuf}});
m_ipuGraph.setTileMapping(vtx, 0);
m_ipuGraph.setPerfEstimate(vtx, 100);
poplar::ComputeSet P_LoadSectors_CS = m_ipuGraph.addComputeSet("P_LoadSectors_CS");
vtx = m_ipuGraph.addVertex(P_LoadSectors_CS, "P_LoadSectors_Vertex", {
{"lumpNum", m_lumpNum}, {"lumpBuf", m_lumpBuf}});
m_ipuGraph.setTileMapping(vtx, 0);
m_ipuGraph.setPerfEstimate(vtx, 100);
poplar::ComputeSet P_LoadSideDefs_CS = m_ipuGraph.addComputeSet("P_LoadSideDefs_CS");
vtx = m_ipuGraph.addVertex(P_LoadSideDefs_CS, "P_LoadSideDefs_Vertex", {
{"lumpNum", m_lumpNum}, {"lumpBuf", m_lumpBuf}});
m_ipuGraph.setTileMapping(vtx, 0);
m_ipuGraph.setPerfEstimate(vtx, 100);
poplar::ComputeSet P_LoadLineDefs_CS = m_ipuGraph.addComputeSet("P_LoadLineDefs_CS");
vtx = m_ipuGraph.addVertex(P_LoadLineDefs_CS, "P_LoadLineDefs_Vertex", {
{"lumpNum", m_lumpNum}, {"lumpBuf", m_lumpBuf}});
m_ipuGraph.setTileMapping(vtx, 0);
m_ipuGraph.setPerfEstimate(vtx, 100);
poplar::ComputeSet P_LoadSubsectors_CS = m_ipuGraph.addComputeSet("P_LoadSubsectors_CS");
vtx = m_ipuGraph.addVertex(P_LoadSubsectors_CS, "P_LoadSubsectors_Vertex", {
{"lumpNum", m_lumpNum}, {"lumpBuf", m_lumpBuf}});
m_ipuGraph.setTileMapping(vtx, 0);
m_ipuGraph.setPerfEstimate(vtx, 100);
poplar::program::Sequence G_DoLoadLevel_prog({
poplar::program::Copy(miscValuesStream, m_miscValuesBuf),
poplar::program::Execute(G_DoLoadLevel_CS),
poplar::program::Execute(P_SetupLevel_CS),
poplar::program::Copy(m_lumpNum, lumpNumStream),
poplar::program::Copy(lumpBufStream, m_lumpBuf),
poplar::program::Execute(P_LoadBlockMap_CS),
poplar::program::Copy(m_lumpNum, lumpNumStream),
poplar::program::Copy(lumpBufStream, m_lumpBuf),
poplar::program::Execute(P_LoadVertexes_CS),
poplar::program::Copy(m_lumpNum, lumpNumStream),
poplar::program::Copy(lumpBufStream, m_lumpBuf),
poplar::program::Execute(P_LoadSectors_CS),
poplar::program::Copy(m_lumpNum, lumpNumStream),
poplar::program::Copy(lumpBufStream, m_lumpBuf),
poplar::program::Execute(P_LoadSideDefs_CS),
poplar::program::Copy(m_lumpNum, lumpNumStream),
poplar::program::Copy(lumpBufStream, m_lumpBuf),
poplar::program::Execute(P_LoadLineDefs_CS),
poplar::program::Copy(m_lumpNum, lumpNumStream),
poplar::program::Copy(lumpBufStream, m_lumpBuf),
poplar::program::Execute(P_LoadSubsectors_CS),
poplar::program::Repeat(9, poplar::program::Sequence({
poplar::program::Execute(P_SetupLevel_CS),
poplar::program::Copy(m_lumpNum, lumpNumStream),
poplar::program::Sync(poplar::SyncType::GLOBAL), // lumpnum must arrive before lump is loaded
poplar::program::Copy(lumpBufStream, m_lumpBuf),
})),
GetPrintbuf_prog,
});
@@ -241,6 +196,27 @@ void IpuDoom::buildIpuGraph() {
});
// -------- R_RenderPlayerView_CS ------ //
poplar::Tensor R_RenderPlayerView_MiscValsBuf = m_ipuGraph.addVariable(poplar::UNSIGNED_CHAR, {sizeof(R_RenderPlayerView_MiscValues_t)}, "R_RenderPlayerView_MiscValsBuf");
m_ipuGraph.setTileMapping(R_RenderPlayerView_MiscValsBuf, 0);
auto R_RenderPlayerView_MiscValsBufStream =
m_ipuGraph.addHostToDeviceFIFO("R_RenderPlayerView_MiscValsBuf-stream", poplar::UNSIGNED_CHAR, sizeof(R_RenderPlayerView_MiscValues_t));
poplar::ComputeSet R_RenderPlayerView_CS = m_ipuGraph.addComputeSet("R_RenderPlayerView_CS");
vtx = m_ipuGraph.addVertex(R_RenderPlayerView_CS, "R_RenderPlayerView_Vertex",
{{"frame", ipuFrame}, {"miscValues", R_RenderPlayerView_MiscValsBuf}});
m_ipuGraph.setTileMapping(vtx, 0);
m_ipuGraph.setPerfEstimate(vtx, 10000000);
poplar::program::Sequence R_RenderPlayerView_prog({
poplar::program::Copy(R_RenderPlayerView_MiscValsBufStream, R_RenderPlayerView_MiscValsBuf),
poplar::program::Copy(frameInStream, ipuFrame),
poplar::program::Execute(R_RenderPlayerView_CS),
poplar::program::Copy(ipuFrame, frameOutStream),
});
// ---------------- Final prog --------------//
printf("Creating engine...\n");
@@ -251,32 +227,32 @@ void IpuDoom::buildIpuGraph() {
G_Ticker_prog,
G_Responder_prog,
AM_Drawer_prog,
R_RenderPlayerView_prog
})));
m_ipuEngine->connectStream("frame-instream", I_VideoBuffer);
m_ipuEngine->connectStream("frame-outstream", I_VideoBuffer);
m_ipuEngine->connectStream("miscValues-stream", m_miscValuesBuf_h);
m_ipuEngine->connectStream("lumpNum-stream", &m_lumpNum_h);
m_ipuEngine->connectStreamToCallback("printbuf-stream", [](void* p) {
if (((char*)p)[0] == '\0') return;
printf("[IPU] %.*s\n", IPUPRINTBUFSIZE, (char*)p);
});
m_ipuEngine->connectStream("miscValues-stream", m_miscValuesBuf_h);
m_ipuEngine->connectStream("lumpNum-stream", &m_lumpNum_h);
m_ipuEngine->connectStreamToCallback("lumpBuf-stream", [this](void* p) {
IPU_LoadLumpForTransfer(m_lumpNum_h, (byte*) p);
});
m_ipuEngine->connectStreamToCallback("marknumSpriteBuf-stream", [this](void* p) {
IPU_Setup_PackMarkNums(p);
});
m_ipuEngine->connectStreamToCallback("R_RenderPlayerView_MiscValsBuf-stream", [this](void* p) {
IPU_R_RenderPlayerView_PackMiscValues(p);
});
m_ipuEngine->load(m_ipuDevice);
}
// --- Internal interface from class IpuDoom to m_ipuEngine --- //
void IpuDoom::run_IPU_Setup() { m_ipuEngine->run(0); }
void IpuDoom::run_G_DoLoadLevel() { IPU_G_LoadLevel_PackMiscValues(m_miscValuesBuf_h); m_ipuEngine->run(1); }
void IpuDoom::run_G_Ticker() { IPU_G_Ticker_PackMiscValues(m_miscValuesBuf_h); m_ipuEngine->run(2); }
@@ -285,14 +261,19 @@ void IpuDoom::run_G_Responder(G_Responder_MiscValues_t* src_buf) {
m_ipuEngine->run(3);
}
void IpuDoom::run_AM_Drawer() { m_ipuEngine->run(4); }
void IpuDoom::run_R_RenderPlayerView() { m_ipuEngine->run(5); }
static std::unique_ptr<IpuDoom> ipuDoomInstance = nullptr;
// --- External interface from C to class IpuDoom --- //
extern "C" {
void IPU_Init() {
ipuDoomInstance = std::make_unique<IpuDoom>();
ipuDoomInstance->run_IPU_Setup();
}
void IPU_AM_Drawer() { ipuDoomInstance->run_AM_Drawer(); }
void IPU_R_RenderPlayerView() { ipuDoomInstance->run_R_RenderPlayerView(); }
void IPU_G_DoLoadLevel() { ipuDoomInstance->run_G_DoLoadLevel(); }
void IPU_G_Ticker() { ipuDoomInstance->run_G_Ticker(); }
void IPU_G_Responder(G_Responder_MiscValues_t* buf) { ipuDoomInstance->run_G_Responder(buf); }

View File

@@ -11,6 +11,7 @@ extern "C" {
void IPU_Init(void);
void IPU_AM_Drawer(void);
void IPU_R_RenderPlayerView(void);
void IPU_G_DoLoadLevel(void);
void IPU_G_Ticker(void);

View File

@@ -81,6 +81,13 @@ void IPU_G_Responder_PackMiscValues(void* src_buf, void* dst_buf) {
memcpy(dst_buf, src_buf, sizeof(G_Responder_MiscValues_t));
}
void IPU_R_RenderPlayerView_PackMiscValues(void* buf) {
R_RenderPlayerView_MiscValues_t* pack = (R_RenderPlayerView_MiscValues_t*) buf;
pack->displayplayer = displayplayer;
pack->players_displayplayer = players[displayplayer];
pack->displayplayer_mo = *players[displayplayer].mo;
}
void IPU_Setup_PackMarkNums(void* buf) {
int bufpos = 10 * sizeof(short);
char namebuf[9] = "AMMNUM0\0";

View File

@@ -12,6 +12,7 @@ extern "C" {
void IPU_G_LoadLevel_PackMiscValues(void* buf);
void IPU_G_Ticker_PackMiscValues(void* buf);
void IPU_G_Responder_PackMiscValues(void* src_buf, void* dst_buf);
void IPU_R_RenderPlayerView_PackMiscValues(void* buf);
void IPU_LoadLumpForTransfer(int lumpnum, byte* buf);
void IPU_Setup_PackMarkNums(void* buf);
void IPU_NotifyLineMapped(line_t *line);

View File

@@ -681,8 +681,9 @@ void P_SpawnMapThing(mapthing_t *mthing) {
if (mthing->type <= 4) {
// save spots for respawning in network games
playerstarts[mthing->type - 1] = *mthing;
if (!deathmatch)
if (!deathmatch) {
P_SpawnPlayer(mthing);
}
return;
}

View File

@@ -429,9 +429,6 @@ void P_LoadLineDefs(int lump) {
ld->backsector = 0;
}
printf("[CPU] numlines: %d, sidenum0: %d, sidenum-1: %d, dx-1: %d\n",
numlines, lines[0].sidenum[1], lines[numlines-1].sidenum[1], lines[numlines-1].dx);
W_ReleaseLumpNum(lump);
}

View File

@@ -41,6 +41,8 @@
#include "r_things.h"
#include "tables.h"
#include "ipu_host.h"
// Fineangles in the SCREENWIDTH wide window.
#define FIELDOFVIEW 2048
@@ -744,6 +746,7 @@ void R_RenderPlayerView(player_t *player) {
NetUpdate();
R_DrawMasked();
IPU_R_RenderPlayerView();
// Check for new console commands.
NetUpdate();