reference system

added some kind of reference system (see list.h) to ensure particles/projectiles/enemies storing pointers to each other that they will not access a borked address.
This commit is contained in:
laochailan 2011-05-13 19:03:02 +02:00
parent eae73f77ad
commit 91b3b7d65e
25 changed files with 477 additions and 252 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 300 KiB

After

Width:  |  Height:  |  Size: 609 KiB

BIN
gfx/items/bullet_point.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 565 B

157
gfx/items/bullet_point.svg Normal file
View file

@ -0,0 +1,157 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="232.38969"
height="232.38969"
id="svg2"
version="1.1"
inkscape:version="0.48.1 r9760"
sodipodi:docname="point.svg"
inkscape:export-filename="/home/laochailan/power.png"
inkscape:export-xdpi="6.1964884"
inkscape:export-ydpi="6.1964884">
<defs
id="defs4">
<linearGradient
id="linearGradient3795">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop3797" />
<stop
style="stop-color:#ff8a65;stop-opacity:1;"
offset="1"
id="stop3799" />
</linearGradient>
<linearGradient
id="linearGradient3763">
<stop
style="stop-color:#001962;stop-opacity:1;"
offset="0"
id="stop3765" />
<stop
style="stop-color:#002b8a;stop-opacity:1;"
offset="1"
id="stop3767" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3763"
id="linearGradient3769"
x1="98.428574"
y1="251.6479"
x2="323"
y2="251.6479"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.89238176,0,0,0.89238176,-439.68548,26.182169)" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3795"
id="radialGradient3801"
cx="250.74817"
cy="251.64787"
fx="250.74817"
fy="251.64787"
r="73.50135"
gradientTransform="matrix(1,0,0,1.1626409,0,-40.928237)"
gradientUnits="userSpaceOnUse" />
<filter
inkscape:collect="always"
id="filter3921"
x="-0.12093023"
width="1.2418605"
y="-0.12093023"
height="1.2418605">
<feGaussianBlur
inkscape:collect="always"
stdDeviation="12.30897"
id="feGaussianBlur3923" />
</filter>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#606060"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:zoom="2.8"
inkscape:cx="76.849368"
inkscape:cy="107.92439"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:window-width="1920"
inkscape:window-height="1039"
inkscape:window-x="0"
inkscape:window-y="-2"
inkscape:window-maximized="1" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-134.55331,-135.45305)">
<path
sodipodi:type="arc"
style="opacity:0.57086618000000000;fill:#fff4ca;fill-opacity:1;fill-rule:evenodd;stroke:none;filter:url(#filter3921)"
id="path3099"
sodipodi:cx="30"
sodipodi:cy="43.103977"
sodipodi:rx="122.14286"
sodipodi:ry="122.14286"
d="m 152.14286,43.103977 a 122.14286,122.14286 0 1 1 -244.28572,0 122.14286,122.14286 0 1 1 244.28572,0 z"
transform="matrix(0.59495854,0,0,0.59495854,232.89941,226.00282)" />
<path
id="path3850"
style="font-size:180.6544342px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Sans"
d="m 217.95599,243.42177 c -7.14506,0.16155 -5.22028,18.09918 0.95313,20.16677 18.43254,6.17341 39.88408,6.17341 58.31662,0 6.17341,-2.06759 6.11592,-21.76327 0,-19.53135 -18.3787,6.70706 -53.88478,-0.75717 -59.26975,-0.63542 z m 74.91703,-26.66408 c 2.48244,-0.50802 2.49441,7.15614 0,7.60169 -13.9651,2.49441 -28.96033,-4.04219 -42.55837,0 -4.04218,1.20159 0,8.43399 0,12.65099 11.57824,0 26.41586,-8.05309 34.73473,0 8.05308,7.7958 10.20343,28.98638 0,33.62499 -22.44418,10.20343 -53.10827,11.47427 -75.55244,1.27084 -10.20343,-4.63862 -5.96663,-26.61657 1.58854,-34.89583 6.8944,-7.55517 20.45613,0 30.6842,0 0,-11.63373 -11.04615,-38.55174 0,-34.9012 2.92902,0.96799 5.64884,8.20289 12.80722,11.35506 10.78809,4.75049 27.61841,5.47858 38.29612,3.29346 z"
inkscape:connector-curvature="0" />
<path
style="font-size:180.6544342px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Sans"
inkscape:connector-curvature="0"
id="path3848"
d="m 204.875,288.78769 c 4.62694,-7.0729 7.94303,-11.40241 11.23428,-16.64244 1.42674,-2.27154 8.21094,0.35686 7.49072,2.9408 -1.38151,4.95644 -5.15283,13.36429 -11.5672,19.41678 -0.9512,0.89754 -10.68379,-0.32519 -7.1578,-5.71514 z" />
<path
style="font-size:180.6544342px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Sans"
inkscape:connector-curvature="0"
id="path3846"
d="m 237.48646,295.35677 c -1.2648,-4.88254 -3.82924,-9.86311 -5.07436,-17.12705 -0.39702,-2.31623 7.81783,-4.24298 8.98351,-2.14119 2.85908,5.15514 4.21524,9.92851 4.96874,17.54354 0.26518,2.67994 -7.38758,7.47777 -8.87789,1.7247 z" />
<path
style="font-size:180.6544342px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Sans"
inkscape:connector-curvature="0"
id="path3844"
d="m 262.39906,294.55593 c -1.54075,-4.11854 -4.97318,-13.65741 -6.26553,-16.65765 -1.04122,-2.41726 7.15033,-2.27946 9.39697,-0.90837 2.62025,1.5991 5.47996,12.1519 5.30255,14.40327 -0.58271,7.39475 -6.58724,8.09921 -8.43399,3.16275 z"
sodipodi:nodetypes="sssss" />
<path
style="font-size:180.6544342px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Sans"
inkscape:connector-curvature="0"
id="path3838"
d="m 287.34735,292.11689 c -1.88424,-3.33752 -8.44796,-13.58474 -11.09376,-17.91864 -1.37139,-2.24637 3.98638,-4.11724 6.61815,-4.0908 5.29027,0.0532 12.13811,13.51197 12.29925,16.84917 0.15067,3.12043 -4.37,11.27766 -7.82364,5.16027 z"
sodipodi:nodetypes="sssss" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.9 KiB

View file

@ -16,7 +16,7 @@
version="1.1"
inkscape:version="0.48.1 r9760"
sodipodi:docname="power.svg"
inkscape:export-filename="/home/laochailan/src/taisei/gfx/items/point.png"
inkscape:export-filename="/home/laochailan/power.png"
inkscape:export-xdpi="6.1964884"
inkscape:export-ydpi="6.1964884">
<defs
@ -35,11 +35,11 @@
<linearGradient
id="linearGradient3763">
<stop
style="stop-color:#001962;stop-opacity:1;"
style="stop-color:#800000;stop-opacity:1;"
offset="0"
id="stop3765" />
<stop
style="stop-color:#002b8a;stop-opacity:1;"
style="stop-color:#ff4800;stop-opacity:1;"
offset="1"
id="stop3767" />
</linearGradient>
@ -73,8 +73,8 @@
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:zoom="0.35"
inkscape:cx="19.603278"
inkscape:cy="107.92439"
inkscape:cx="-99.396394"
inkscape:cy="60.585693"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
@ -112,7 +112,7 @@
height="232.38969"
width="232.38969"
id="rect3813"
style="fill:#001697;fill-opacity:1;stroke:none" />
style="fill:#970d00;fill-opacity:1;stroke:none" />
<rect
style="fill:url(#linearGradient3769);fill-opacity:1;stroke:#ffffff;stroke-width:19.52022361999999944;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="rect2985"
@ -123,30 +123,10 @@
ry="18.930275"
transform="matrix(0,-1,1,0,0,0)" />
<path
id="path3850"
style="font-size:180.6544342px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Sans"
d="m 198.61679,238.57041 c -11.35887,0.25682 -8.29895,28.77317 1.51523,32.06013 29.30315,9.81418 63.40574,9.81418 92.70889,0 9.81418,-3.28696 9.72279,-34.59818 0,-31.04998 -29.21755,10.66255 -85.66337,-1.20371 -94.22412,-1.01015 z m 119.09939,-42.38925 c 3.94647,-0.80762 3.9655,11.37648 0,12.08479 -22.20103,3.9655 -46.0397,-6.42606 -67.6572,0 -6.42606,1.91023 0,13.40795 0,20.11192 18.40652,0 41.99464,-12.8024 55.21956,0 12.8024,12.39338 16.22091,46.08112 0,53.45536 -35.68064,16.22091 -84.4289,18.24122 -120.10954,2.02031 -16.22091,-7.37424 -9.48545,-42.31371 2.52538,-55.47567 10.96038,-12.01083 32.52015,0 48.78023,0 0,-18.49473 -17.56062,-61.28764 0,-55.4842 4.65642,1.53886 8.98025,13.04055 20.36029,18.05171 17.15038,7.5521 43.90638,8.70958 60.88128,5.23578 z" />
<path
style="font-size:180.6544342px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Sans"
id="path3847"
style="fill:#ffffff;fill-opacity:1;stroke:none"
d="m 229.75045,202.95593 c 11.5343,-8.31412 40.88286,-0.7841 42.72511,12.14286 1.83113,12.84898 -24.31631,26.22078 -37.79529,20.71428 -11.4988,-4.69755 -14.71028,-25.80721 -4.92982,-32.85714 z m -44.3684,-8.57142 c -1.44723,30.77936 0.71692,92.49464 2.4649,127.14285 0.59399,11.77379 33.83542,15.3775 40.26021,5 10.81049,-17.46139 5.89667,-65.67221 8.21638,-65 0,0 88.11291,13.93991 79.69879,-55.71428 -4.62903,-38.32027 -128.83009,-49.92742 -130.64028,-11.42857 z"
inkscape:connector-curvature="0"
id="path3848"
d="m 177.82128,310.6909 c 7.35568,-11.24414 12.62743,-18.12699 17.85969,-26.45733 2.26817,-3.61117 13.05336,0.56732 11.90838,4.67514 -2.19626,7.8795 -8.19171,21.24589 -18.38896,30.86784 -1.51217,1.42686 -16.98456,-0.51697 -11.37911,-9.08565 z" />
<path
style="font-size:180.6544342px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Sans"
inkscape:connector-curvature="0"
id="path3846"
d="m 229.66537,321.13411 c -2.01072,-7.76203 -6.08754,-15.6799 -8.06697,-27.22774 -0.63117,-3.68223 12.42839,-6.74528 14.28153,-3.40396 4.54523,8.19538 6.70118,15.78385 7.89907,27.88985 0.42157,4.26044 -11.74442,11.88779 -14.11363,2.74185 z" />
<path
style="font-size:180.6544342px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Sans"
inkscape:connector-curvature="0"
id="path3844"
d="m 269.27019,319.86096 c -2.44941,-6.54745 -7.90612,-21.71187 -9.96063,-26.48151 -1.65529,-3.84283 11.36724,-3.62377 14.93883,-1.44408 4.16555,2.54217 8.71178,19.31849 8.42974,22.89761 -0.92637,11.75581 -10.47208,12.87573 -13.40794,5.02798 z"
sodipodi:nodetypes="sssss" />
<path
style="font-size:180.6544342px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Sans"
inkscape:connector-curvature="0"
id="path3838"
d="m 308.93175,315.98351 c -2.99547,-5.30584 -13.43015,-21.59636 -17.63631,-28.48617 -2.18017,-3.57118 6.33734,-6.54539 10.5212,-6.50336 8.41021,0.0845 19.29657,21.48067 19.55274,26.78598 0.23953,4.9607 -6.94721,17.92866 -12.43763,8.20355 z"
sodipodi:nodetypes="sssss" />
sodipodi:nodetypes="ssssssscss" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 206 B

View file

@ -1,111 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="8"
height="16"
id="svg2"
version="1.1"
inkscape:version="0.48.1 r9760"
sodipodi:docname="laserline.svg"
inkscape:export-filename="/home/laochailan/src/taisei/gfx/laserline.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90">
<defs
id="defs4">
<linearGradient
id="linearGradient3755">
<stop
style="stop-color:#0017ff;stop-opacity:0;"
offset="0"
id="stop3757" />
<stop
id="stop3771"
offset="0.10036337"
style="stop-color:#0017ff;stop-opacity:0.86086959;" />
<stop
id="stop3769"
offset="0.25449884"
style="stop-color:#ffffff;stop-opacity:1;" />
<stop
id="stop3767"
offset="0.74988341"
style="stop-color:#ffffff;stop-opacity:1;" />
<stop
id="stop3763"
offset="0.89999998"
style="stop-color:#0017ff;stop-opacity:0.86086959;" />
<stop
style="stop-color:#0017ff;stop-opacity:0;"
offset="1"
id="stop3759" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3755"
id="linearGradient3761"
x1="89.666855"
y1="103.77428"
x2="89.666855"
y2="118.77636"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.6000001,0,0,1.0666665,-52.285719,-7.9193741)" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="34.733333"
inkscape:cx="-2.6535509"
inkscape:cy="5.196737"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:snap-page="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:window-width="1920"
inkscape:window-height="1039"
inkscape:window-x="0"
inkscape:window-y="-2"
inkscape:window-maximized="1" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-87.14286,-102.79076)">
<rect
style="fill:url(#linearGradient3761);fill-opacity:1;fill-rule:nonzero;stroke:none"
id="rect2985"
width="8"
height="16"
x="87.14286"
y="102.79073"
ry="0" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.2 KiB

View file

@ -131,11 +131,18 @@ void process_boss(Boss *boss) {
void boss_death(Boss **boss) {
free_boss(*boss);
*boss = NULL;
delete_projectiles(&global.projs);
Projectile *p;
for(p = global.projs; p; p = p->next)
if(p->type == FairyProj)
p->type = DeadProj;
delete_lasers(&global.lasers);
}
void free_boss(Boss *boss) {
del_ref(boss);
free(boss->name);
int i;
for(i = 0; i < boss->acount; i++)

View file

@ -44,19 +44,20 @@ typedef struct Attack {
} Attack;
typedef struct Boss {
char *name;
Attack *attacks;
Attack *current;
int acount;
Animation *ani;
int anirow;
complex pos;
complex pos0;
int time0;
char *name;
int acount;
Animation *ani;
int anirow;
int dmg;
} Boss;

View file

@ -43,6 +43,8 @@ void create_enemy(Enemy **enemies, EnemyDrawRule draw_rule, EnemyLogicRule logic
void _delete_enemy(void **enemies, void* enemy) {
((Enemy* )enemy)->logic_rule(enemy, EVENT_DEATH);
del_ref(enemy);
delete_element((void **)enemies, enemy);
}

View file

@ -28,11 +28,11 @@ typedef struct Enemy {
struct Enemy *next;
struct Enemy *prev;
long birthtime;
complex pos;
complex pos0;
long birthtime;
int dir; // TODO: deprecate those
int moving;

View file

@ -31,7 +31,7 @@ Texture *load_text(const char *text, TTF_Font *font) {
void draw_text(const char *text, int x, int y, TTF_Font *font) {
char *nl;
char *buf = malloc(strlen(text));
char *buf = malloc(strlen(text)+1);
strcpy(buf, text);
if((nl = strchr(buf, '\n')) != NULL && strlen(nl) > 1) {

View file

@ -18,6 +18,7 @@
#include "laser.h"
#include "shader.h"
#include "dialog.h"
#include "list.h"
enum {
SCREEN_W = 800,
@ -33,6 +34,8 @@ enum {
SNDSRC_COUNT = 30,
ACTION_DESTROY,
EVENT_DEATH = -8999,
EVENT_BIRTH,
@ -48,6 +51,8 @@ typedef struct {
Item *items;
Laser *lasers;
Projectile *particles;
int frames;
int lasttime;
int timer;
@ -70,6 +75,8 @@ typedef struct {
ALuint sndsrc[SNDSRC_COUNT];
RefArray refs; // for super extra OOP-tardness: references. the cool way.
int game_over;
int points;

View file

@ -10,7 +10,7 @@
#include "global.h"
#include "list.h"
void create_item(complex pos, complex v, Type type) {
Item *create_item(complex pos, complex v, Type type) {
Item *i = create_element((void **)&global.items, sizeof(Item));
i->pos = pos;
i->pos0 = pos;
@ -18,6 +18,8 @@ void create_item(complex pos, complex v, Type type) {
i->birthtime = global.frames;
i->auto_collect = 0;
i->type = type;
return i;
}
@ -28,23 +30,26 @@ void delete_item(Item *item) {
void draw_items() {
Item *p;
Texture *tex = NULL;
for(p = global.items; p; p = p->next){
switch(p->type){
case Power:
tex = get_tex("items/power");
break;
case Point:
tex = get_tex("items/point");
break;
case Life:
tex = get_tex("items/life");
break;
case Bomb:
tex = get_tex("items/bomb");
break;
default:
break;
}
for(p = global.items; p; p = p->next) {
switch(p->type){
case Power:
tex = get_tex("items/power");
break;
case Point:
tex = get_tex("items/point");
break;
case Life:
tex = get_tex("items/life");
break;
case Bomb:
tex = get_tex("items/bomb");
break;
case BPoint:
tex = get_tex("items/bullet_point");
break;
default:
break;
}
draw_texture_p(creal(p->pos), cimag(p->pos), tex);
}
}
@ -58,7 +63,7 @@ void move_item(Item *i) {
complex lim = 0 + 2I;
if(i->auto_collect)
i->pos -= 7*cexp(I*carg(i->pos - global.plr.pos));
i->pos -= (7+i->auto_collect)*cexp(I*carg(i->pos - global.plr.pos));
else
i->pos = i->pos0 + log(t/5.0 + 1)*5*(i->v + lim) + lim*t;
}
@ -82,6 +87,9 @@ void process_items() {
case Point:
global.points += 100;
break;
case BPoint:
global.points += 1;
break;
case Life:
global.plr.lifes++;
break;

View file

@ -17,6 +17,7 @@ struct Item;
typedef enum {
Power,
Point,
BPoint,
Life,
Bomb
} Type;
@ -35,7 +36,7 @@ typedef struct Item{
complex v;
} Item;
void create_item(complex pos, complex v, Type type);
Item *create_item(complex pos, complex v, Type type);
void delete_item(Item *item);
void draw_items();
void delete_items();

View file

@ -9,12 +9,15 @@
#include <stdlib.h>
#include <stdio.h>
#include "global.h"
typedef struct {
void *next;
void *prev;
} List;
void *_FREEREF;
void *create_element(void **dest, int size) {
void *last = *dest;
void *e = malloc(size);
@ -33,7 +36,7 @@ void *create_element(void **dest, int size) {
return e;
}
void delete_element(void **dest, void *e) {
void delete_element(void **dest, void *e) {
if(((List *)e)->prev != NULL)
((List *)((List *)e)->prev)->next = ((List *)e)->next;
if(((List *)e)->next != NULL)
@ -52,7 +55,36 @@ void delete_all_elements(void **dest, void (callback)(void **, void *)) {
tmp = e;
e = ((List *)e)->next;
callback(dest, tmp);
}
}
*dest = NULL;
}
int add_ref(void *ptr) {
int i;
for(i = 0; i < global.refs.count; i++) {
if(global.refs.ptrs[i] == FREEREF) {
global.refs.ptrs[i] = ptr;
return i;
}
}
global.refs.ptrs = realloc(global.refs.ptrs, (++global.refs.count)*sizeof(void *));
global.refs.ptrs[global.refs.count - 1] = ptr;
return global.refs.count - 1;
}
void del_ref(void *ptr) {
int i;
for(i = 0; i < global.refs.count; i++)
if(global.refs.ptrs[i] == ptr)
global.refs.ptrs[i] = NULL;
}
void free_ref(int i) {
if(i >= 0)
REF(i) = FREEREF;
}

View file

@ -16,4 +16,15 @@ void *create_element(void **dest, int size);
void delete_element(void **dest, void *e);
void delete_all_elements(void **dest, void (callback)(void **, void *));
typedef struct {
void **ptrs;
int count;
} RefArray;
extern void *_FREEREF;
#define FREEREF &_FREEREF
#define REF(p) (global.refs.ptrs[(int)p])
int add_ref(void *ptr);
void del_ref(void *ptr);
void free_ref(int i);
#endif

View file

@ -106,8 +106,16 @@ void player_logic(Player* plr) {
float a = 1;
if(plr->focus > 0)
a = 0.2;
if(plr->shot == YoumuHoming && !(global.frames % 7))
create_projectile("hghost", plr->pos, NULL, youmu_homing, a*cexp(I*rand()))->type = PlrProj;
if(plr->shot == YoumuHoming && !(global.frames % 7)) {
complex ref = -1;
if(global.boss != NULL)
ref = add_ref(global.boss);
else if(global.enemies != NULL)
ref = add_ref(global.enemies);
if(ref != -1)
create_projectile("hghost", plr->pos, NULL, youmu_homing, a*cexp(I*rand()), ref)->type = PlrProj;
}
}
if(plr->focus < 0 || (plr->focus > 0 && plr->focus < 30))

View file

@ -34,20 +34,21 @@ void youmu_opposite_logic(Enemy *e, int t) {
e->pos0 = e->pos + plr->pos;
}
void youmu_homing(Projectile *p, int t) { // a[0]: velocity
p->angle = t/30.0;
int youmu_homing(Projectile *p, int t) { // a[0]: velocity, a[1]: target, a[2]: old velocity
// p->angle = t/30.0;
if(t == EVENT_DEATH) {
free_ref(p->args[1]);
}
complex tv = 0;
complex tv = p->args[2];
if(REF(p->args[1]) != NULL)
tv = cexp(I*carg(((Enemy *)REF(p->args[1]))->pos - p->pos));
if(global.enemies != NULL)
tv = cexp(I*carg(global.enemies[0].pos - p->pos));;
if(global.boss != NULL)
tv = cexp(I*carg(global.boss->pos - p->pos));;
if(t > 150 || tv == 0)
tv = - ((rand()%3)-1)/2.0 - 0.5I;
p->args[2] = tv;
p->pos += p->args[0]*log(t + 1) + tv*t/15.0;
p->pos += p->args[0]*log(t + 1) + tv*t*t/300.0;
p->pos0 = p->pos;
return 1;
}

View file

@ -14,6 +14,6 @@
void youmu_opposite_draw(Enemy *e, int t);
void youmu_opposite_logic(Enemy *e, int t);
void youmu_homing(Projectile *p, int t);
int youmu_homing(Projectile *p, int t);
#endif

View file

@ -26,39 +26,82 @@ inline Color *rgb(float r, float g, float b) {
return rgba(r, g, b, 1.0);
}
Projectile *create_projectile_d(Projectile **dest, char *name, complex pos, Color *clr,
ProjRule rule, complex args, ...) {
Projectile *create_particle(char *name, complex pos, Color *clr, ProjDRule draw, ProjRule rule, complex arg1, ...) {
va_list ap;
complex a[4];
int i;
memset(a, 0, sizeof(a));
va_start(ap, arg1);
a[0] = arg1;
for(i = 1; i < 4; i++) {
a[i] = va_arg(ap, complex);
}
va_end(ap);
return create_projectile_dv(&global.particles, name, pos, clr, draw, rule, a);
}
Projectile *create_projectile(char *name, complex pos, Color *clr, ProjRule rule, complex arg1, ...) {
va_list ap;
complex a[4], ar;
int i;
memset(a, 0, sizeof(a));
va_start(ap, arg1);
a[0] = arg1;
for(i = 1; i < 4; i++) {
a[i] = va_arg(ap, complex);
}
va_end(ap);
return create_projectile_dv(&global.projs, name, pos, clr, ProjDraw, rule, a);
}
Projectile *create_projectile_dv(Projectile **dest, char *name, complex pos, Color *clr,
ProjDRule draw, ProjRule rule, complex *args) {
Projectile *p = create_element((void **)dest, sizeof(Projectile));
char buf[128];
strcpy(buf, "proj/");
strcat(buf, name);
if(name[0] == '!')
strncpy(buf, name+1, sizeof(buf));
else {
strcpy(buf, "proj/");
strcat(buf, name);
}
p->birthtime = global.frames;
p->pos = pos;
p->pos0 = pos;
p->angle = 0;
p->rule = rule;
p->draw = draw;
p->tex = get_tex(buf);
p->type = FairyProj;
p->clr = clr;
p->parent = NULL;
memcpy(p->args, args, sizeof(p->args));
va_list ap;
int i;
va_start(ap, args);
for(i = 0; i < 4 && args; i++) {
p->args[i++] = args;
args = va_arg(ap, complex);
if(dest != &global.particles && clr != NULL) {
Color *color = rgba(clr->r, clr->g, clr->b, clr->a);
create_particle(name, pos, color, Shrink, bullet_flare_move, add_ref(p));
}
va_end(ap);
return p;
}
void _delete_projectile(void **projs, void *proj) {
free(((Projectile*)proj)->clr);
((Projectile *)proj)->rule(proj, EVENT_DEATH);
if(((Projectile*)proj)->clr)
free(((Projectile*)proj)->clr);
del_ref(proj);
delete_element(projs, proj);
}
@ -99,42 +142,35 @@ int collision_projectile(Projectile *p) {
void draw_projectiles(Projectile *projs) {
Projectile *proj;
GLuint shader = get_shader("bullet_color");
glUseProgramObjectARB(shader);
for(proj = projs; proj; proj = proj->next) {
if(proj->clr == NULL)
glUseProgramObjectARB(0);
glUniform4fv(glGetUniformLocation(shader, "color"), 1, (GLfloat *)proj->clr);
glPushMatrix();
glTranslatef(creal(proj->pos), cimag(proj->pos), 0);
glRotatef(proj->angle*180/M_PI+90, 0, 0, 1);
draw_texture_p(0,0, proj->tex);
glPopMatrix();
if(proj->clr == NULL)
glUseProgramObjectARB(shader);
}
glUseProgramObjectARB(0);
for(proj = projs; proj; proj = proj->next)
proj->draw(proj, global.frames - proj->birthtime);
}
void process_projectiles(Projectile **projs, short collision) {
void process_projectiles(Projectile **projs, char collision) {
Projectile *proj = *projs, *del = NULL;
char killed = 0;
char col = 0;
int action;
while(proj != NULL) {
proj->rule(proj, global.frames - proj->birthtime);
action = proj->rule(proj, global.frames - proj->birthtime);
int v = 0;
if(proj->type == DeadProj && killed < 2) {
killed++;
action = ACTION_DESTROY;
create_particle("!lasercurve", proj->pos, NULL, Fade, timeout, 20);
create_item(proj->pos, 0, BPoint)->auto_collect = 10;
}
if(collision)
v = collision_projectile(proj);
col = collision_projectile(proj);
if(v == 1 && (global.frames - abs(global.plr.recovery)) >= 0)
if(col == 1 && (global.frames - abs(global.plr.recovery)) >= 0)
plr_death(&global.plr);
if(v || creal(proj->pos) + proj->tex->w/2 < 0 || creal(proj->pos) - proj->tex->w/2 > VIEWPORT_W
|| cimag(proj->pos) + proj->tex->h/2 < 0 || cimag(proj->pos) - proj->tex->h/2 > VIEWPORT_H) {
if(action == ACTION_DESTROY || col
|| creal(proj->pos) + proj->tex->w/2 < 0 || creal(proj->pos) - proj->tex->w/2 > VIEWPORT_W
|| cimag(proj->pos) + proj->tex->h/2 < 0 || cimag(proj->pos) - proj->tex->h/2 > VIEWPORT_H) {
del = proj;
proj = proj->next;
delete_projectile(projs, del);
@ -145,7 +181,73 @@ void process_projectiles(Projectile **projs, short collision) {
}
}
void linear(Projectile *p, int t) { // sure is physics in here; a[0]: velocity
int linear(Projectile *p, int t) { // sure is physics in here; a[0]: velocity
p->angle = carg(p->args[0]);
p->pos = p->pos0 + p->args[0]*t;
return 1;
}
void ProjDraw(Projectile *proj, int t) {
if(proj->clr != NULL) {
GLuint shader = get_shader("bullet_color");
glUseProgramObjectARB(shader);
glUniform4fv(glGetUniformLocation(shader, "color"), 1, (GLfloat *)proj->clr);
}
glPushMatrix();
glTranslatef(creal(proj->pos), cimag(proj->pos), 0);
glRotatef(proj->angle*180/M_PI+90, 0, 0, 1);
draw_texture_p(0,0, proj->tex);
glPopMatrix();
glUseProgramObjectARB(0);
}
void Shrink(Projectile *p, int t) {
if(p->clr != NULL) {
GLuint shader = get_shader("bullet_color");
glUseProgramObjectARB(shader);
glUniform4fv(glGetUniformLocation(shader, "color"), 1, (GLfloat *)p->clr);
}
glPushMatrix();
float s = 2.0-t/8.0;
glTranslatef(creal(p->pos), cimag(p->pos), 0);
glRotatef(p->angle, 0, 0, 1);
glScalef(s, s, 1);
draw_texture_p(0, 0, p->tex);
glPopMatrix();
glUseProgramObjectARB(0);
}
int bullet_flare_move(Projectile *p, int t) {
int i;
if(t > 16 || REF(p->args[0]) == NULL) {
free_ref(p->args[0]);
return ACTION_DESTROY;
}
p->pos = ((Projectile *) REF(p->args[0]))->pos;
p->angle = ((Projectile *) REF(p->args[0]))->angle;
return 1;
}
void Fade(Projectile *p, int t) {
glColor4f(1,1,1,(float)t/p->args[0]);
draw_texture_p(creal(p->pos), cimag(p->pos), p->tex);
glColor4f(1,1,1,1);
}
int timeout(Projectile *p, int t) {
if(t >= creal(p->args[0]))
return ACTION_DESTROY;
return 1;
}

View file

@ -21,24 +21,26 @@ typedef struct {
} Color;
struct Projectile;
typedef void (*ProjRule)(struct Projectile *p, int t);
typedef int (*ProjRule)(struct Projectile *p, int t);
typedef void (*ProjDRule)(struct Projectile *p, int t);
typedef struct Projectile {
struct Projectile *next;
struct Projectile *prev;
long birthtime;
complex pos;
complex pos0;
long birthtime;
float angle;
void *parent;
ProjRule rule;
ProjDRule draw;
Texture *tex;
enum { PlrProj, FairyProj } type;
enum { PlrProj, FairyProj, DeadProj } type;
Color *clr;
@ -51,14 +53,23 @@ Color *rgba(float r, float g, float b, float a);
inline Color *rgb(float r, float g, float b);
#define create_particle(name, pos, clr, rule, args) (create_projectile_d(&global.particles, name, pos, clr, rule, args))
#define create_projectile(name, pos, clr, rule, args) (create_projectile_d(&global.projs, name, pos, clr, rule, args))
Projectile *create_projectile_d(Projectile **dest, char *name, complex pos, Color *clr, ProjRule rule, complex args, ...);
Projectile *create_particle(char *name, complex pos, Color *clr, ProjDRule draw, ProjRule rule, complex arg1, ...);
Projectile *create_projectile(char *name, complex pos, Color *clr, ProjRule rule, complex arg1, ...);
Projectile *create_projectile_dv(Projectile **dest, char *name, complex pos, Color *clr, ProjDRule draw, ProjRule rule, complex *args);
void delete_projectile(Projectile **dest, Projectile *proj);
void delete_projectiles(Projectile **dest);
void draw_projectiles(Projectile *projs);
int collision_projectile(Projectile *p);
void process_projectiles(Projectile **projs, short collision);
void process_projectiles(Projectile **projs, char collision);
void linear(Projectile *p, int t);
Projectile *get_proj(Projectile *hay, int birthtime);
int linear(Projectile *p, int t);
void ProjDraw(Projectile *p, int t);
void Shrink(Projectile *p, int t);
int bullet_flare_move(Projectile *p, int t);
void Fade(Projectile *p, int t);
int timeout(Projectile *p, int t);
#endif

View file

@ -12,7 +12,7 @@
#include <err.h>
void print_info_log(GLuint shader) {
int len, alen;
int len = 0, alen = 0;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len);
if(len > 1) {

View file

@ -11,14 +11,15 @@
#include "global.h"
#include "font.h"
SDL_Event event;
void stage_start() {
init_player(&global.plr, Youmu, YoumuHoming);
global.timer = 0;
}
void stage_input() {
void stage_input() {
SDL_Event event;
memset(&event, 0, sizeof(event));
while(SDL_PollEvent(&event)) {
if(event.type == SDL_KEYDOWN) {
switch(event.key.keysym.sym) {
@ -127,11 +128,13 @@ void stage_draw() {
draw_projectiles(global.projs);
draw_enemies(global.enemies);
draw_items();
draw_lasers();
draw_lasers();
if(global.boss)
draw_boss(global.boss);
draw_projectiles(global.particles);
if(global.dialog)
draw_dialog(global.dialog);
@ -170,7 +173,7 @@ void apply_bg_shaders() {
glPushMatrix();
glTranslatef(-global.rtt.nw+VIEWPORT_W,-global.rtt.nh+VIEWPORT_H,0);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, global.rtt.tex);
glBegin(GL_QUADS);
@ -192,6 +195,7 @@ void stage_logic() {
process_projectiles(&global.projs, True);
process_items();
process_lasers();
process_projectiles(&global.particles, False);
if(global.boss) {
process_boss(global.boss);

View file

@ -34,6 +34,7 @@ Dialog *test_dialog() {
dadd_msg(d, Left, "Hello");
dadd_msg(d, Right, "Hello you");
dadd_msg(d, Right, "Uhm ... who are you?\nNew line.\nAnother longer line.");
dadd_msg(d, Left, "idk");
return d;
}
@ -130,8 +131,11 @@ complex lolsin(Laser *l, float t) {
return pos;
}
void cirno_pfreeze_frogs(Projectile *p, int t) {
int boss_t = (global.frames - *((int *)p->parent)) % 320;
int cirno_pfreeze_frogs(Projectile *p, int t) {
if(*((Boss**)p->parent) == NULL || (*(Boss**)p->parent)->current == NULL)
return 1;
int boss_t = (global.frames - (*(Boss**)p->parent)->current->starttime) % 320;
if(boss_t < 110)
linear(p, t);
@ -147,7 +151,8 @@ void cirno_pfreeze_frogs(Projectile *p, int t) {
if(t > 240)
linear(p, t-240);
return 1;
}
void cirno_perfect_freeze(Boss *c, int time) {
@ -160,7 +165,7 @@ void cirno_perfect_freeze(Boss *c, int time) {
}
if(time > 10 && time < 80)
create_projectile("ball", c->pos, rgb(rand()/(float)RAND_MAX, rand()/(float)RAND_MAX, rand()/(float)RAND_MAX), cirno_pfreeze_frogs, 4*cexp(I*rand()))->parent=&c->current->starttime;
create_projectile("ball", c->pos, rgb(rand()/(float)RAND_MAX, rand()/(float)RAND_MAX, rand()/(float)RAND_MAX), cirno_pfreeze_frogs, 4*cexp(I*rand()))->parent=&global.boss;
if(time > 160 && time < 220 && !(time % 7)) {
create_projectile("rice", c->pos + 60, rgb(0.3, 0.4, 0.9), linear, 5*cexp(I*carg(global.plr.pos - c->pos)));
create_projectile("rice", c->pos - 60, rgb(0.3, 0.4, 0.9), linear, 5*cexp(I*carg(global.plr.pos - c->pos)));
@ -169,13 +174,12 @@ void cirno_perfect_freeze(Boss *c, int time) {
}
void cirno_pfreeze_bg(Boss *c, int time) {
glColor4f(1,1,1,1);
fill_screen(time/700.0, time/700.0, 2, "cirnobg");
glColor4f(1,1,1,0.5);
fill_screen(time/700.0, time/700.0+0.5, 2, "cirnobg");
glColor4f(0.5,0.5,0.5,1);
fill_screen(time/700.0, time/700.0, 1, "cirnobg");
glColor4f(0.7,0.7,0.7,0.5);
fill_screen(-time/700.0 + 0.5, time/700.0+0.5, 0.4, "cirnobg");
fill_screen(0, -time/100.0, 0, "snowlayer");
// draw_texture(VIEWPORT_W/2,VIEWPORT_H/2, "snowlayer");
glColor4f(1,1,1,1);
}

View file

@ -49,7 +49,7 @@ void recurse_dir(char *path) {
void load_resources() {
printf("load_resources():\n");
char *path = malloc(sizeof(FILE_PREFIX)+4);
char *path = malloc(sizeof(FILE_PREFIX)+7);
printf("- textures:\n");
strcpy(path, FILE_PREFIX);