From 8516b33391c3c0475abdceb1c9f97aba78c87ea8 Mon Sep 17 00:00:00 2001 From: Allanis <allanis@saracraft.net> Date: Wed, 25 Sep 2013 20:45:14 +0100 Subject: [PATCH] [Add] Beam weapons now render properly. --- dat/outfit.xml | 1 + dat/ship.xml | 3 +- gfx/outfit/space/beam_ragnarok.png | Bin 0 -> 1206 bytes src/opengl.c | 4 +++ src/outfit.c | 21 ++++++++++--- src/outfit.h | 10 +++++- src/weapon.c | 49 ++++++++++++++++++++++++----- 7 files changed, 74 insertions(+), 14 deletions(-) create mode 100644 gfx/outfit/space/beam_ragnarok.png diff --git a/dat/outfit.xml b/dat/outfit.xml index 5d87879..5a225e2 100644 --- a/dat/outfit.xml +++ b/dat/outfit.xml @@ -163,6 +163,7 @@ <turn>50</turn> <energy>130</energy> <damage type="energy">100</damage> + <gfx>beam_ragnarok</gfx> </specific> </outfit> <outfit name="Seeker Launcher"> diff --git a/dat/ship.xml b/dat/ship.xml index e4b8dc8..4dcbdaf 100644 --- a/dat/ship.xml +++ b/dat/ship.xml @@ -238,7 +238,8 @@ <cap_cargo>10</cap_cargo> </characteristics> <outfits> - <outfit quantity="2">Ripper MK2</outfit> + <outfit quantity="2">Ripper MK2</outfit> + <outfit quantity="1">Ragnarok Beam</outfit> <outfit quantity="1">Headhunter Launcher</outfit> <outfit quantity="20">Headhunter</outfit> </outfits> diff --git a/gfx/outfit/space/beam_ragnarok.png b/gfx/outfit/space/beam_ragnarok.png new file mode 100644 index 0000000000000000000000000000000000000000..50d624580a45c7c768d114e81f72f361ebcf36ca GIT binary patch literal 1206 zcmZ8gYfuwc6uwzPc8LT6#33QEEFpBR6k||ipg!1ygonHWqmEDoRGbE-7Lb;L3d;%> z0)sqSTSZEULDICfJgikhHSvLUKnSR9qy=>BI4C{}#m5v<y7ZURbLYF?Ip2?a=G=2m zl{zt+!}ehV064KR$`qRMMPMxY-d|iiOA}*%O0)u;85BLD1DD*G)cpV~@md4}oH)s+ zMYJF`L512;5hh%-*OGplmRLLEqLpA_@#ubPZv=oD8mp9V;tQOuH}kSm1<sar6Xv8n z*;ifpvJIVmXpPk^XGa99qYTq~J5Dv2#@A<^E}grcJs#E)e))xRWv|TYC4FdpaMgXV zajtoO<HbDR8F`6c#PsEym$qxE&kB8hsS+M7tlhey<mi0(z6g8M#p~03nHk$6!o3f4 zPfS-Flnu>V-J~-E_uduE>fKZFcieiPa^N4%cJ&T)U1})bnd`sy;~VnlcI?8i6+Mzu zEb}&>^p=X?GfZ%hOGJFr*_+Y+R()=QfhYIUw)%N5LxhoWpBC9FP`6co=-cEsY<}Li z_5`hMf5A8B9f^H{dWmr$w>QcAb!ezV;^+Ri4!z4X!-S`JjWp?^rti3MQZ~deCo@&* zFgqqC<!WXU>4d>A)dhvw>8Zo4UA8EKS%+u&1181cTl&iM5~#QnFNk}%`IT{UO+52G zLx@K0!?t4puqCsIKGZWO{^=5PwIhmEzq$tvmN5yy6OdxMp>-qtJ2*_({n7oTu=wcj zD>d0y>PGN-gu$b>C=V-Cz_LZBNsw)SU0o1zI5W$pj#rUD%Y~Gux*UMyaw2)_<HEcS z_f;k_2r=+nAZ3z3#6Z-O=MYWIsdF7!{{(h(Yq0Oc`al6lbKwGc_6;4W6C01YaL*<z zy#96<hR3Kw5zrbS_dqlZNLk&MI}?hy*xwL(UfwXv8~%T;>;DAH%&XEvtE(^t8ERy5 z*z5pCnnWK6fmp|;(O<gYND5NA;#vrB5`kixDX|Hm#4zZQ@2E$l9zaYBbU0-qX$>(V z82hq#;fk@cl3d&a5+OVQj{zV8d+ZaENU@$HX3)<-98wK{U9N>xAUNw;J#Vok53>vm z4yZs7NY_AA>#&WR)!R=z=hsw90t4ynM*y+-`&<J0=wZ**!UMhyc11MBZ3UauAHd@# zY{UeXR~p$`UfHNk+T8MXq<<Br7b=3GAjg&Rgl;K>$7jqYkzpyX(IhSE-AifwUFtw< zjGC!pI6<2y30T6`%F#A+{|^((^uLCoRog>|pTQW+B)6R<GaFUD5<3y89r;=i^@U^p zk>}DDbdC+0T*q9s9-9?QGy}Jze46vQ%w=h8EUl~O;DtllNoA){9=d`vw;TyD`T0Ka z^6KtCjdtI?R-0&D2lMaa!j^%@`K9Jr|CeY|hB`lYOwjq&g?)x6euc%WR*KqoXJCR% z&WgD~QNf-wf5xY+|D=3sN0DRb-1zxKQPA(tg4={me|<i+wmUq1(!DlgYI;p=#kHXP w5#iL2J>w6~PjW8Zd#9))BfO+5ee10SC+C}4!*kqYCl+TQR+XqcqsXNG1?YLZ$^ZZW literal 0 HcmV?d00001 diff --git a/src/opengl.c b/src/opengl.c index 45f2256..30ce204 100644 --- a/src/opengl.c +++ b/src/opengl.c @@ -313,6 +313,10 @@ static GLuint gl_loadSurface(SDL_Surface* surface, int *rw, int* rh) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + /* Always wrap just in case. */ + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + /* Now lead the texture data up. */ SDL_LockSurface(surface); glTexImage2D(GL_TEXTURE_2D, 0, surface->format->BytesPerPixel, diff --git a/src/outfit.c b/src/outfit.c index 12cb330..9efc09f 100644 --- a/src/outfit.c +++ b/src/outfit.c @@ -280,6 +280,7 @@ int outfit_isMap(const Outfit* o) { */ glTexture* outfit_gfx(const Outfit* o) { if(outfit_isBolt(o)) return o->u.blt.gfx_space; + else if(outfit_isBeam(o)) return o->u.bem.gfx; else if(outfit_isAmmo(o)) return o->u.amm.gfx_space; else if(outfit_isTurret(o)) return o->u.blt.gfx_space; return NULL; @@ -561,22 +562,32 @@ static void outfit_parseSBolt(Outfit* tmp, const xmlNodePtr parent) { */ static void outfit_parseSBeam(Outfit* tmp, const xmlNodePtr parent) { xmlNodePtr node; - + char str[PATH_MAX] = "\0"; + node = parent->xmlChildrenNode; do { /* Load all the data. */ xmlr_float(node, "range", tmp->u.bem.range); xmlr_float(node, "turn", tmp->u.bem.turn); xmlr_float(node, "energy", tmp->u.bem.energy); xmlr_long(node, "delay", tmp->u.bem.delay); + xmlr_float(node, "warmup", tmp->u.bem.warmup); xmlr_float(node, "duration", tmp->u.bem.duration); - if(xml_isNode(node, "damage")) + if(xml_isNode(node, "damage")) { outfit_parseDamage(&tmp->u.bem.dtype, &tmp->u.bem.damage, node); + continue; + } + + if(xml_isNode(node, "gfx")) { + snprintf(str, strlen(xml_get(node))+sizeof(OUTFIT_GFX)+10, + OUTFIT_GFX"space/%s.png", xml_get(node)); + tmp->u.bem.gfx = gl_newSprite(str, 1, 1); + continue; + } } while(xml_nextNode(node)); - tmp->u.bem.colour = &cWhite; /** @todo Make it loadable. */ - #define MELEMENT(o,s) if(0) WARN("Outfit '%s' missing/invalid '"s"' element", tmp->name) + MELEMENT(tmp->u.bem.gfx==NULL, "gfx"); MELEMENT(tmp->u.bem.delay==0, "range"); MELEMENT(tmp->u.bem.duration==0, "duration"); MELEMENT(tmp->u.bem.range==0, "range"); @@ -590,8 +601,8 @@ static void outfit_parseSBeam(Outfit* tmp, const xmlNodePtr parent) { /* Parse the specific area for a launcher and loads it into Outfit. */ static void outfit_parseSLauncher(Outfit* tmp, const xmlNodePtr parent) { xmlNodePtr node; + node = parent->xmlChildrenNode; - do { /* Load the dataz. */ if(xml_isNode(node, "delay")) tmp->u.lau.delay = xml_getInt(node); diff --git a/src/outfit.h b/src/outfit.h index 5a96911..e4ba241 100644 --- a/src/outfit.h +++ b/src/outfit.h @@ -52,6 +52,7 @@ typedef struct OutfitBoltData_ { DamageType dtype; /**< Damage type. */ double damage; /**< damage. */ + /* Sound and graphics. */ glTexture* gfx_space; /**< Graphic. */ int sound; /**< Sound to play. */ int spfx; /**< Special effect on hit. */ @@ -63,14 +64,21 @@ typedef struct OutfitBoltData_ { * @brief Represents the particular properties of a beam weapon. */ typedef struct OutfitBeamData_ { + /* Time stuff. */ unsigned int delay; /**< Delay between usage. */ - unsigned int duration; /**< How long the beam lasts active. */ + double warmup; /**< How long it takes to warm up. */ + double duration; /**< How long the beam lasts active. */ + + /* Beam properties. */ double range; /**< How far it goes. */ double turn; /**< How fast it can turn. Only for turrets. */ glColour* colour; /**< Beam colour. */ double energy; /**< Amount of energy it drains (per second). */ DamageType dtype; /**< Damage type. */ double damage; /**< Damage amount. */ + + /* Graphics */ + glTexture* gfx; /**< Base texture. */ } OutfitBeamData; /** diff --git a/src/weapon.c b/src/weapon.c index 78d7635..5d9a5b3 100644 --- a/src/weapon.c +++ b/src/weapon.c @@ -373,16 +373,51 @@ static void weapon_render(const Weapon* w) { /* Beam weapons. */ case OUTFIT_TYPE_BEAM: case OUTFIT_TYPE_TURRET_BEAM: + gfx = outfit_gfx(w->outfit); x = w->solid->pos.x - VX(*gl_camera) + gui_xoff; y = w->solid->pos.y - VY(*gl_camera) + gui_yoff; - ACOLOUR(*w->outfit->u.bem.colour, 0.8); - glLineWidth(3.); - glBegin(GL_LINES); - glVertex2d(x, y); - glVertex2d(x + w->outfit->u.bem.range * cos(w->solid->dir), - y + w->outfit->u.bem.range * sin(w->solid->dir)); + + /* Set up the matrix. */ + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glTranslated(x, y, 0.); + glRotated(270. + w->solid->dir / M_PI * 180., 0., 0., 1.); + + /* Preparatives. */ + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, gfx->texture); + glShadeModel(GL_SMOOTH); + + /* Actual rendering. */ + glBegin(GL_QUAD_STRIP); + COLOUR(cWhite); + + /* Full strength. */ + glTexCoord2d(0., 0.); + glVertex2d(-gfx->sh/2., 0.); + + glTexCoord2d(0., 1.); + glVertex2d(+gfx->sh/2., 0.); + + glTexCoord2d(0.8*w->outfit->u.bem.range / gfx->sw, 0.); + glVertex2d(+gfx->sh/2., 0.8*w->outfit->u.bem.range); + + /* Fades out. */ + ACOLOUR(cWhite, 0.); + + glTexCoord2d(w->outfit->u.bem.range / gfx->sw, 0.); + glVertex2d(-gfx->sh/2., w->outfit->u.bem.range); + + glTexCoord2d(w->outfit->u.bem.range / gfx->sw, 1.); + glVertex2d(+gfx->sh/2., w->outfit->u.bem.range); glEnd(); - glLineWidth(1.); + + /* Clean up. */ + glDisable(GL_TEXTURE_2D); + glShadeModel(GL_FLAT); + glPopMatrix(); + gl_checkErr(); + break; default: