improved headers / conditional compilation

This commit is contained in:
Zeno Rogue 2017-12-02 00:31:36 +01:00
parent 9c789c6591
commit 5defb06d81
9 changed files with 258 additions and 223 deletions

View File

@ -3,8 +3,6 @@
// cells the game is played on
#define DEBMEM(x) // { x fflush(stdout); }
int fix6(int a) { return (a+MODFIXER)%S6; }
int fix7(int a) { return (a+MODFIXER)%S7; }
@ -45,14 +43,6 @@ struct cdata {
// -- hrmap ---
struct hrmap {
virtual heptagon *getOrigin() { return NULL; }
virtual cell *gamestart() { return getOrigin()->c7; }
virtual ~hrmap() { };
virtual vector<cell*>& allcells() { return dcal; }
virtual void verify() { }
};
hrmap *currentmap;
vector<hrmap*> allmaps;
@ -66,36 +56,24 @@ struct hrmap_alternate : hrmap {
hrmap *newAltMap(heptagon *o) { return new hrmap_alternate(o); }
// --- hyperbolic geometry ---
struct hrmap_hyperbolic : hrmap {
heptagon *origin;
bool isnontruncated;
hrmap_hyperbolic() {
// printf("Creating hyperbolic map: %p\n", this);
origin = new heptagon;
heptagon& h = *origin;
h.s = hsOrigin;
h.emeraldval = 98;
h.zebraval = 40;
h.fiftyval = 0;
h.fieldval = 0;
h.rval0 = h.rval1 = 0;
h.cdata = NULL;
for(int i=0; i<MAX_EDGE; i++) h.move[i] = NULL;
h.spintable = 0;
h.alt = NULL;
h.distance = 0;
isnontruncated = nontruncated;
h.c7 = newCell(S7, origin);
}
heptagon *getOrigin() { return origin; }
~hrmap_hyperbolic() {
DEBMEM ( verifycells(origin); )
// printf("Deleting hyperbolic map: %p\n", this);
dynamicval<bool> ph(nontruncated, isnontruncated);
clearfrom(origin);
}
void verify() { verifycells(origin); }
};
hrmap_hyperbolic::hrmap_hyperbolic() {
// printf("Creating hyperbolic map: %p\n", this);
origin = new heptagon;
heptagon& h = *origin;
h.s = hsOrigin;
h.emeraldval = 98;
h.zebraval = 40;
h.fiftyval = 0;
h.fieldval = 0;
h.rval0 = h.rval1 = 0;
h.cdata = NULL;
for(int i=0; i<MAX_EDGE; i++) h.move[i] = NULL;
h.spintable = 0;
h.alt = NULL;
h.distance = 0;
isnontruncated = nontruncated;
h.c7 = newCell(S7, origin);
}
// --- spherical geometry ---

View File

@ -214,3 +214,5 @@ extern geometryinfo ginf[gGUARD];
extern monstertype minf[motypes];
extern itemtype iinf[ittypes];
extern const landtype linf[landtypes];

View File

@ -165,12 +165,6 @@ extern int hrand(int);
// a structure used to walk on the heptagonal tesselation
// (remembers not only the heptagon, but also direction)
struct heptspin {
heptagon *h;
int spin;
bool mirrored;
heptspin() { mirrored = false; }
};
heptspin hsstep(const heptspin &hs, int spin) {
createStep(hs.h, hs.spin);

150
hyper.h
View File

@ -26,6 +26,8 @@ typedef long double ld;
#define ASINH asinhl
#endif
#define DEBMEM(x) // { x fflush(stdout); }
struct hyperpoint {
ld tab[3];
ld& operator [] (int i) { return tab[i]; }
@ -38,6 +40,23 @@ struct transmatrix {
const ld * operator [] (int i) const { return tab[i]; }
};
inline hyperpoint operator * (const transmatrix& T, const hyperpoint& H) {
hyperpoint z;
for(int i=0; i<3; i++) {
z[i] = 0;
for(int j=0; j<3; j++) z[i] += T[i][j] * H[j];
}
return z;
}
inline transmatrix operator * (const transmatrix& T, const transmatrix& U) {
transmatrix R;
// for(int i=0; i<3; i++) for(int j=0; j<3; j++) R[i][j] = 0;
for(int i=0; i<3; i++) for(int j=0; j<3; j++) // for(int k=0; k<3; k++)
R[i][j] = T[i][0] * U[0][j] + T[i][1] * U[1][j] + T[i][2] * U[2][j];
return R;
}
// cell information for the game
struct gcell {
@ -143,7 +162,12 @@ struct heptagon {
unsigned char gspin(int i) { return spin(fixrot(i)); }
};
struct heptspin;
struct heptspin {
heptagon *h;
int spin;
bool mirrored;
heptspin() { mirrored = false; }
};
struct cell : gcell {
char type; // 6 for hexagons, 7 for heptagons
@ -203,7 +227,9 @@ string cts(char c);
string its(int i);
int hrand(int i);
#ifndef STDSIZE
template<class T> int size(const T& x) {return int(x.size()); }
#endif
extern int currentscore[NUMLEADER];
extern int syncstate;
@ -406,6 +432,46 @@ namespace shmup {
void clearMemory();
void init();
void teleported();
struct monster {
eMonster type;
cell *base;
cell *torigin;
// tortoises: origin
// butterflies: last position
transmatrix at;
transmatrix pat;
eMonster stk;
bool dead;
bool notpushed;
bool inBoat;
monster *parent; // who shot this missile
eMonster parenttype; // type of the parent
int nextshot; // when will it be able to shot (players/flailers)
int pid; // player ID
char hitpoints;
int stunoff;
int blowoff;
double swordangle; // sword angle wrt at
double vel; // velocity, for flail balls
double footphase;
bool isVirtual; // off the screen: gmatrix is unknown, and pat equals at
monster() {
dead = false; inBoat = false; parent = NULL; nextshot = 0;
stunoff = 0; blowoff = 0; footphase = 0;
}
void store();
void findpat();
cell *findbase(const transmatrix& T);
void rebasePat(const transmatrix& new_pat);
};
extern struct monster* mousetarget;
extern eItem targetRangedOrb(orbAction a);
void degradeDemons();
@ -425,9 +491,11 @@ namespace shmup {
void virtualRebase(cell*& base, transmatrix& at, bool tohex);
void virtualRebase(shmup::monster *m, bool tohex);
transmatrix calc_relative_matrix(cell *c, heptagon *h1);
void fixStorage();
void addShmupHelp(string& out);
void activateArrow(cell *c);
transmatrix& ggmatrix(cell *c);
}
// graph
@ -1057,6 +1125,7 @@ void checkStunKill(cell *dest);
void clearMessages();
void resetGeometry();
extern bool nontruncated;
namespace svg {
void circle(int x, int y, int size, int col);
@ -1346,8 +1415,6 @@ namespace arg {
void read(int phase);
#else
inline void read(int phase) { }
#endif
}
@ -1556,7 +1623,7 @@ template<class T, class... U> void callhooks(hookset<T> *h, U... args) {
if(h) for(auto& p: *h) p.second(args...);
}
template<class T, class V, class... U> V callhandlers(V zero, hookset<T> *h, U... args) {
template<class T, class V, class... U> V callhandlers(V zero, hookset<T> *h, U&... args) {
if(h) for(auto& p: *h) {
auto z = p.second(args...);
if(z != zero) return z;
@ -1843,7 +1910,7 @@ struct qline {
double width;
};
#define MAXQCHR 40
#define MAXQCHR 64
struct qchr {
char str[MAXQCHR];
@ -2030,7 +2097,28 @@ int polarb50(cell *c);
bool isGravityLand(eLand l);
bool isWarped(eLand l);
struct hrmap;
struct hrmap {
virtual heptagon *getOrigin() { return NULL; }
virtual cell *gamestart() { return getOrigin()->c7; }
virtual ~hrmap() { };
virtual vector<cell*>& allcells() { return dcal; }
virtual void verify() { }
};
struct hrmap_hyperbolic : hrmap {
heptagon *origin;
bool isnontruncated;
hrmap_hyperbolic();
heptagon *getOrigin() { return origin; }
~hrmap_hyperbolic() {
DEBMEM ( verifycells(origin); )
// printf("Deleting hyperbolic map: %p\n", this);
dynamicval<bool> ph(nontruncated, isnontruncated);
clearfrom(origin);
}
void verify() { verifycells(origin); }
};
extern hrmap *currentmap;
extern vector<hrmap*> allmaps;
@ -2123,7 +2211,55 @@ static const auto SKIPFAC = .4;
bool haveMobileCompass();
bool handleCompass();
bool sphereflipped() { return sphere && vid.alpha > 1.1; }
inline bool sphereflipped() { return sphere && vid.alpha > 1.1; }
int cellcolor(cell *c);
transmatrix screenpos(ld x, ld y);
extern ld backbrightness;
void initcells();
void precalc();
extern const hyperpoint C0;
extern const transmatrix Id;
extern long long circlesize[100], disksize[100];
extern ld circlesizeD[10000];
void computeSizes();
#if CAP_FILES
extern const char *scorefile;
extern const char *conffile;
extern string levelfile;
extern string picfile;
extern const char *musicfile;
extern const char *loadlevel;
#endif
transmatrix spin(ld alpha);
transmatrix xpush(ld alpha);
transmatrix inverse(const transmatrix&);
ld hdist(const hyperpoint& h1, const hyperpoint& h2);
extern bool fixseed;
extern eLand firstland0;
extern int startseed;
extern transmatrix heptmove[MAX_EDGE], hexmove[MAX_EDGE];
extern transmatrix invheptmove[MAX_EDGE], invhexmove[MAX_EDGE];
heptspin hsstep(const heptspin &hs, int spin);
extern void fixmatrix(transmatrix&);
void display(const transmatrix& T);
transmatrix rgpushxto0(const hyperpoint& H);
char *display(const hyperpoint& H);
extern int cellcount, heptacount;
string its(int i);
double hdist0(const hyperpoint& mh);
extern bool fading;
extern ld fadeout;
int itemclass(eItem i);

View File

@ -150,15 +150,6 @@ const transmatrix MirrorX = {{{-1,0,0}, {0,1,0}, {0,0,1}}};
// rotate by PI
const transmatrix pispin = {{{-1,0,0}, {0,-1,0}, {0,0,1}}};
hyperpoint operator * (const transmatrix& T, const hyperpoint& H) {
hyperpoint z;
for(int i=0; i<3; i++) {
z[i] = 0;
for(int j=0; j<3; j++) z[i] += T[i][j] * H[j];
}
return z;
}
// T * C0, optimized
inline hyperpoint tC0(const transmatrix &T) {
hyperpoint z;
@ -166,14 +157,6 @@ inline hyperpoint tC0(const transmatrix &T) {
return z;
}
inline transmatrix operator * (const transmatrix& T, const transmatrix& U) {
transmatrix R;
// for(int i=0; i<3; i++) for(int j=0; j<3; j++) R[i][j] = 0;
for(int i=0; i<3; i++) for(int j=0; j<3; j++) // for(int k=0; k<3; k++)
R[i][j] = T[i][0] * U[0][j] + T[i][1] * U[1][j] + T[i][2] * U[2][j];
return R;
}
// rotate by alpha degrees
transmatrix spin(ld alpha) {
transmatrix T = Id;
@ -305,8 +288,6 @@ transmatrix rgpushxto0(const hyperpoint& H) {
// fix the matrix T so that it is indeed an isometry
// (without using this, imprecision could accumulate)
void display(const transmatrix& T);
void fixmatrix(transmatrix& T) {
if(euclid) {
for(int x=0; x<2; x++) for(int y=0; y<=x; y++) {

View File

@ -74,6 +74,10 @@
#define EXTERNALFONT
#endif
#ifndef CAP_FILES
#define CAP_FILES 1
#endif
#ifndef CAP_INV
#define CAP_INV 1
#endif
@ -113,7 +117,7 @@
#endif
#ifndef CAP_EDIT
#define CAP_EDIT (!ISWEB && !ISMINI)
#define CAP_EDIT (CAP_FILES && !ISWEB && !ISMINI)
#endif
#ifndef CAP_MODEL
@ -121,11 +125,11 @@
#endif
#ifndef CAP_SAVE
#define CAP_SAVE (!ISWEB && !ISMINI)
#define CAP_SAVE (CAP_FILES && !ISWEB && !ISMINI)
#endif
#ifndef CAP_CONFIG
#define CAP_CONFIG (!ISWEB && !ISMINI)
#define CAP_CONFIG (CAP_FILES && !ISWEB && !ISMINI)
#endif
#ifndef CAP_TRANS
@ -161,6 +165,13 @@
#define CAP_SVG (!ISMOBILE)
#endif
#ifndef CAP_POLY
#define CAP_POLY (CAP_SDLGFX || CAP_GL || CAP_SVG)
#endif
#define CAP_QUEUE CAP_POLY
#define CAP_CURVE CAP_POLY
#ifndef CAP_SDLJOY
#define CAP_SDLJOY (CAP_SDL && !ISWEB)
#endif
@ -282,6 +293,7 @@ inline Uint8 *SDL_GetKeyState(void *v) { static Uint8 tab[1024]; return tab; }
#define CAP_GLEW (CAP_GL && !ISMOBILE && !ISMAC && !ISLINUX)
#endif
#if CAP_GL
#if CAP_GLEW
#include <GL/glew.h>
#else
@ -302,6 +314,7 @@ inline Uint8 *SDL_GetKeyState(void *v) { static Uint8 tab[1024]; return tab; }
#include <GL/glext.h>
#endif
#endif
#endif
#include <functional>
#include <memory>
@ -355,15 +368,6 @@ FILE *debfile;
FILE *debugfile;
int debugflags;
#if CAP_COMMANDLINE
const char *scorefile = "hyperrogue.log";
const char *conffile = "hyperrogue.ini";
string levelfile = "hyperrogue.lev";
string picfile = "hyperrogue.pic";
const char *musicfile = "";
const char *loadlevel = NULL;
#endif
string s0;
bool fixseed = false;
@ -374,7 +378,9 @@ eLand firstland0;
void initAll() {
showstartmenu = true;
ca::init();
#if CAP_COMMANDLINE
arg::read(1);
#endif
srand(time(NULL));
shrand(fixseed ? startseed : time(NULL));

View File

@ -611,9 +611,11 @@ namespace inv {
};
}
#if CAP_SAVE
void applyBox(eItem it) {
applyBoxNum(usedup[it]);
}
#endif
int incheck;

View File

@ -102,12 +102,13 @@ void shift(hpcshape& sh, double dx, double dy, double dz) {
SDL_Surface *aux;
#endif
#define CAP_POLY (CAP_SDLGFX || CAP_GL || CAP_SVG)
#if CAP_POLY
vector<polytodraw*> ptds2;
#define POLYMAX 60000
GLfloat glcoords[POLYMAX][3];
int qglcoords;
#if CAP_GL
GLfloat *currentvertices;
#endif
@ -138,9 +139,6 @@ void initPolyForGL() {
GLuint shapebuffer;
GLfloat glcoords[POLYMAX][3];
int qglcoords;
extern void glcolor(int color);
@ -163,6 +161,7 @@ void activateGlcoords() {
}
#endif
#if CAP_POLY
int polyi;
int polyx[POLYMAX], polyxr[POLYMAX], polyy[POLYMAX];
@ -472,6 +471,10 @@ void fixMercator() {
}
}
unsigned char& part(int& col, int i) {
unsigned char* c = (unsigned char*) &col; return c[i];
}
void drawpolyline(polytodraw& p) {
auto pp = p.u.poly;
@ -605,6 +608,8 @@ void drawpolyline(polytodraw& p) {
if(vid.goteyes) filledPolygonColorI(aux, polyxr, polyy, polyi, p.col);
// part(pp.outline, 0) = part(pp.outline, 0) * linewidthat(tC0(pp.V), pp.minwidth);
((vid.antialias & AA_NOGL) ?aapolylineColor:polylineColor)(s, polyx, polyy, polyi, pp.outline);
if(vid.goteyes) aapolylineColor(aux, polyxr, polyy, polyi, pp.outline);
@ -655,6 +660,7 @@ void prettyline(hyperpoint h1, hyperpoint h2, int col, int lev) {
vector<GLfloat> curvedata;
int curvestart = 0;
bool keep_curvedata = false;
void drawqueueitem(polytodraw& ptd) {
#if CAP_ROGUEVIZ
@ -856,7 +862,9 @@ void drawqueue() {
#endif
setcameraangle(false);
curvedata.clear(); curvestart = 0;
if(!keep_curvedata) {
curvedata.clear(); curvestart = 0;
}
}
hpcshape
@ -2153,10 +2161,6 @@ void initShape(int sg, int id) {
}
}
unsigned char& part(int& col, int i) {
unsigned char* c = (unsigned char*) &col; return c[i];
}
void queuepolyat(const transmatrix& V, const hpcshape& h, int col, int prio) {
polytodraw& ptd = nextptd();
ptd.kind = pkPoly;
@ -2308,7 +2312,7 @@ void queuestr(int x, int y, int shift, int size, string str, int col, int frame
ptd.u.chr.shift = shift;
ptd.u.chr.size = size;
ptd.col = darkened(col);
ptd.u.chr.frame = frame ? ((poly_outline & ~ 255)+1) : 0;
ptd.u.chr.frame = frame ? ((poly_outline & ~ 255)+frame) : 0;
ptd.prio = PPR_TEXT << PSHIFT;
}
@ -3338,3 +3342,5 @@ NEWSHAPE
// fix Warp
// fix Kraken
#endif

186
shmup.cpp
View File

@ -476,8 +476,6 @@ bool notremapped(int sym) {
return k > multi::players;
}
#if CAP_CONFIG
void initConfig() {
vid.scfg.players = 1;
@ -597,6 +595,7 @@ void initConfig() {
for(int i=0; i<7; i++) addsaver(multi::scs[i], "player"+its(i));
}
#if CAP_CONFIG
void scanchar(FILE *f, char& c) {
int i = c;
int err = fscanf(f, "%d", &i);
@ -983,142 +982,73 @@ void fixelliptic(transmatrix& at) {
}
}
struct monster {
eMonster type;
cell *base;
cell *torigin;
// tortoises: origin
// butterflies: last position
transmatrix at;
transmatrix pat;
eMonster stk;
bool dead;
bool notpushed;
bool inBoat;
monster *parent; // who shot this missile
eMonster parenttype; // type of the parent
int nextshot; // when will it be able to shot (players/flailers)
int pid; // player ID
char hitpoints;
int stunoff;
int blowoff;
double swordangle; // sword angle wrt at
double vel; // velocity, for flail balls
double footphase;
bool isVirtual; // off the screen: gmatrix is unknown, and pat equals at
monster() {
dead = false; inBoat = false; parent = NULL; nextshot = 0;
stunoff = 0; blowoff = 0; footphase = 0;
}
void monster::store() {
monstersAt.insert(make_pair(base, this));
}
void store() {
monstersAt.insert(make_pair(base, this));
}
void findpat() {
isVirtual = !gmatrix.count(base);
if(!isVirtual) pat = gmatrix[base] * at;
else pat = at;
}
void monster::findpat() {
isVirtual = !gmatrix.count(base);
if(!isVirtual) pat = gmatrix[base] * at;
else pat = at;
}
cell *findbase(const transmatrix& T) {
if(isVirtual) {
cell *c = base;
auto cT = T;
virtualRebase(c, cT, true);
return c;
}
else return findbaseAround(T, base);
cell *monster::findbase(const transmatrix& T) {
if(isVirtual) {
cell *c = base;
auto cT = T;
virtualRebase(c, cT, true);
return c;
}
else return findbaseAround(T, base);
}
void rebasePat(const transmatrix& new_pat) {
if(isVirtual) {
at = new_pat;
virtualRebase(this, true);
fixmatrix(at); pat = at;
return;
}
if(geometry == gQuotient || geometry == gTorus) {
at = inverse(gmatrix[base]) * new_pat;
virtualRebase(this, true);
fixmatrix(at);
return;
}
pat = new_pat;
cell *c2 = findbase(pat);
// if(c2 != base) printf("rebase %p -> %p\n", base, c2);
base = c2;
at = inverse(gmatrix[c2]) * pat;
void monster::rebasePat(const transmatrix& new_pat) {
if(isVirtual) {
at = new_pat;
virtualRebase(this, true);
fixmatrix(at); pat = at;
return;
}
if(geometry == gQuotient || geometry == gTorus) {
at = inverse(gmatrix[base]) * new_pat;
virtualRebase(this, true);
fixmatrix(at);
fixelliptic(at);
return;
}
pat = new_pat;
cell *c2 = findbase(pat);
// if(c2 != base) printf("rebase %p -> %p\n", base, c2);
base = c2;
at = inverse(gmatrix[c2]) * pat;
fixmatrix(at);
fixelliptic(at);
}
/* void rebaseAt(const transmatrix& new_at) {
rebasePat(gmatrix[base] * new_at);
} */
bool trackroute(monster *m, transmatrix goal, double spd) {
cell *c = m->base;
// queuepoly(goal, shGrail, 0xFFFFFFC0);
bool trackroute(transmatrix goal, double spd) {
cell *c = base;
// queuepoly(goal, shGrail, 0xFFFFFFC0);
transmatrix mat = inverse(m->pat) * goal;
transmatrix mat2 = spintox(mat*C0) * mat;
double d = 0, dist = asinh(mat2[0][2]);
transmatrix mat = inverse(pat) * goal;
transmatrix mat2 = spintox(mat*C0) * mat;
double d = 0, dist = asinh(mat2[0][2]);
while(d < dist) {
d += spd;
transmatrix nat = m->pat * rspintox(mat * C0) * xpush(d);
while(d < dist) {
d += spd;
transmatrix nat = pat * rspintox(mat * C0) * xpush(d);
// queuepoly(nat, shKnife, 0xFFFFFFC0);
// queuepoly(nat, shKnife, 0xFFFFFFC0);
cell *c2 = findbaseAround(nat, c);
if(c2 != c && !passable_for(type, c2, c, P_CHAIN | P_ONPLAYER)) {
return false;
}
c = c2;
cell *c2 = findbaseAround(nat, c);
if(c2 != c && !passable_for(m->type, c2, c, P_CHAIN | P_ONPLAYER)) {
return false;
}
return true;
c = c2;
}
bool trackrouteView(transmatrix goal, double spd) {
cell *c = base;
queuepoly(goal, shGrail, 0xFFFFFFC0);
transmatrix mat = inverse(pat) * goal;
transmatrix mat2 = spintox(mat*C0) * mat;
double d = 0, dist = asinh(mat2[0][2]);
while(d < dist) {
d += spd;
transmatrix nat = pat * rspintox(mat * C0) * xpush(d);
// queuepoly(nat, shKnife, 0xFFFFFFC0);
cell *c2 = findbaseAround(nat, c);
if(c2 != c) {
if(0) printf("old dist: %lf\n", (double) intval(nat*C0, gmatrix[c]*C0));
if(0) printf("new dist: %lf\n", (double) intval(nat*C0, gmatrix[c2]*C0));
}
queuepoly(gmatrix[c2], shKnife, 0xFF0000FF);
if(c2 != c && !passable_for(type, c2, c, P_CHAIN))
return false;
c = c2;
}
if(0) printf("dist = %lf, d = %lf, spd = %lf, lint = %lf, lcd = %lf\n", dist, d, spd,
(double) intval(pat * rspintox(mat * C0) * xpush(d)*C0, goal*C0),
(double) intval(pat * rspintox(mat * C0) * xpush(d)*C0, gmatrix[c]*C0)
);
return true;
}
};
return true;
}
monster *pc[MAXPLAYER], *mousetarget, *lmousetarget;
@ -2466,7 +2396,7 @@ void moveMonster(monster *m, int delta) {
sort(bugtargets.begin(), bugtargets.end(), closer);
for(monster *m2: bugtargets)
if(m->trackroute(m2->pat, step)) {
if(trackroute(m, m2->pat, step)) {
goal = m2->pat;
direct = true;
break;
@ -2511,7 +2441,7 @@ void moveMonster(monster *m, int delta) {
}
else if(!direct && !invismove && !peace::on) {
for(int i=0; i<players; i++)
if(m->trackroute(pc[i]->pat, step) && (!direct || intval(pc[i]->pat*C0, m->pat*C0) < intval(goal*C0,m->pat*C0))) {
if(trackroute(m, pc[i]->pat, step) && (!direct || intval(pc[i]->pat*C0, m->pat*C0) < intval(goal*C0,m->pat*C0))) {
goal = pc[i]->pat;
direct = true;
directi = i;
@ -2520,7 +2450,7 @@ void moveMonster(monster *m, int delta) {
}
if(!direct && !peace::on) while(true) {
if(m->trackroute(gmatrix[c], step))
if(trackroute(m, gmatrix[c], step))
goal = gmatrix[c];
cell *cnext = c;
for(int i=0; i<c->type; i++) {