malloc-less colors

This commit is contained in:
Andrei "Akari" Alexeyev 2017-02-26 22:59:51 +02:00
parent 8e53b1e689
commit 41fa6d9d76
22 changed files with 236 additions and 135 deletions

View file

@ -25,6 +25,7 @@ set(SRCs
taiseigl.c
random.c
config.c
color.c
gamepad.c
stage.c
replay.c

View file

@ -166,7 +166,6 @@ void free_boss(Boss *boss) {
free(boss->name);
free(boss->attacks);
free(boss->zoomcolor);
}
void free_attack(Attack *a) {

View file

@ -10,8 +10,9 @@
#include "tscomplex.h"
#include "difficulty.h"
#include "resource/animation.h"
#include "color.h"
#include <resource/animation.h>
struct Boss;
typedef void (*BossRule)(struct Boss*, int time);
@ -83,7 +84,7 @@ typedef struct Boss {
int anirow;
int dmg;
Color *zoomcolor;
Color zoomcolor;
} Boss;
Boss* create_boss(char *name, char *ani, complex pos);

View file

@ -6,20 +6,105 @@
* Copyright (C) 2012, Alexeyew Andrew <http://akari.thebadasschoobs.org/>
*/
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
#include "color.h"
Color *rgba(float r, float g, float b, float a) {
Color *clr = malloc(sizeof(Color));
clr->r = r;
clr->g = g;
clr->b = b;
clr->a = a;
static const float conv = 1.0f / CLR_ONEVALUE;
return clr;
Color rgba(float r, float g, float b, float a) {
return ((((Color)(CLR_ONEVALUE * (r)) & CLR_CMASK) << CLR_R) + \
(((Color)(CLR_ONEVALUE * (g)) & CLR_CMASK) << CLR_G) + \
(((Color)(CLR_ONEVALUE * (b)) & CLR_CMASK) << CLR_B) + \
(((Color)(CLR_ONEVALUE * (a)) & CLR_CMASK) << CLR_A));
}
Color *rgb(float r, float g, float b) {
return rgba(r, g, b, 1.0);
Color rgb(float r, float g, float b) {
return ((((Color)(CLR_ONEVALUE * (r)) & CLR_CMASK) << CLR_R) + \
(((Color)(CLR_ONEVALUE * (g)) & CLR_CMASK) << CLR_G) + \
(((Color)(CLR_ONEVALUE * (b)) & CLR_CMASK) << CLR_B) + \
(CLR_ONEVALUE << CLR_A));
}
void parse_color(Color clr, float *r, float *g, float *b, float *a) {
*r = (ColorComponent)((clr >> CLR_R) & CLR_CMASK) * conv;
*g = (ColorComponent)((clr >> CLR_G) & CLR_CMASK) * conv;
*b = (ColorComponent)((clr >> CLR_B) & CLR_CMASK) * conv;
*a = (ColorComponent)((clr >> CLR_A) & CLR_CMASK) * conv;
}
void parse_color_call(Color clr, void(*func)(float r, float g, float b, float a)) {
float r, g, b, a;
parse_color(clr, &r, &g, &b, &a);
func(r, g, b, a);
}
void parse_color_array(Color clr, float array[4]) {
parse_color(clr, array, array+1, array+2, array+3);
}
Color derive_color(Color src, Color mask, Color mod) {
return (src & ~mask) | (mod & mask);
}
float color_component(Color clr, unsigned int ofs) {
return (ColorComponent)((clr >> ofs) & CLR_CMASK) * conv;
}
Color multiply_colors(Color c1, Color c2) {
float c1a[4], c2a[4];
parse_color_array(c1, c1a);
parse_color_array(c2, c2a);
return rgba(c1a[0]*c2a[0], c1a[1]*c2a[1], c1a[2]*c2a[2], c1a[3]*c2a[3]);
}
Color add_colors(Color c1, Color c2) {
float c1a[4], c2a[4];
parse_color_array(c1, c1a);
parse_color_array(c2, c2a);
return rgba(c1a[0]+c2a[0], c1a[1]+c2a[1], c1a[2]+c2a[2], c1a[3]+c2a[3]);
}
Color subtract_colors(Color c1, Color c2) {
float c1a[4], c2a[4];
parse_color_array(c1, c1a);
parse_color_array(c2, c2a);
return rgba(c1a[0]-c2a[0], c1a[1]-c2a[1], c1a[2]-c2a[2], c1a[3]-c2a[3]);
}
Color divide_colors(Color c1, Color c2) {
float c1a[4], c2a[4];
parse_color_array(c1, c1a);
parse_color_array(c2, c2a);
return rgba(c1a[0]/c2a[0], c1a[1]/c2a[1], c1a[2]/c2a[2], c1a[3]/c2a[3]);
}
// #define COLOR_TEST
int color_test(void) {
#ifdef COLOR_TEST
float clra[4];
Color clr1, clr2, clr3;
clr1 = rgba(0.1, 0.2, 0.3, 0.4);
parse_color_array(clr1, clra);
clr2 = rgba(clra[0], clra[1], clra[2], clra[3]);
clr3 = derive_color(clr1, CLRMASK_A, rgba(0, 0, 0, -1.0));
printf("1: %016llx (%f %f %f %f)\n", (unsigned long long int)clr1,
color_component(clr1, CLR_R), color_component(clr1, CLR_G), color_component(clr1, CLR_B), color_component(clr1, CLR_A));
printf("2: %016llx (%f %f %f %f)\n", (unsigned long long int)clr2,
color_component(clr2, CLR_R), color_component(clr2, CLR_G), color_component(clr2, CLR_B), color_component(clr2, CLR_A));
printf("3: %016llx (%f %f %f %f)\n", (unsigned long long int)clr3,
color_component(clr3, CLR_R), color_component(clr3, CLR_G), color_component(clr3, CLR_B), color_component(clr3, CLR_A));
assert(clr1 == clr2);
assert(color_component(clr3, CLR_R) == color_component(clr3, CLR_R));
assert(color_component(clr3, CLR_G) == color_component(clr3, CLR_G));
assert(color_component(clr3, CLR_B) == color_component(clr3, CLR_B));
assert(color_component(clr3, CLR_A) == -1.0);
return 1;
#else
return 0;
#endif
}

View file

@ -9,14 +9,35 @@
#ifndef TSCOLOR_H
#define TSCOLOR_H
typedef struct {
float r;
float g;
float b;
float a;
} Color;
#include <stdint.h>
Color* rgba(float r, float g, float b, float a);
Color* rgb(float r, float g, float b);
#define CLR_R 48L
#define CLR_G 32L
#define CLR_B 16L
#define CLR_A 0L
#define CLR_CMASK 0xffffL
#define CLR_ONEVALUE 0xffL
#define CLRMASK_R (CLR_CMASK << CLR_R)
#define CLRMASK_G (CLR_CMASK << CLR_G)
#define CLRMASK_B (CLR_CMASK << CLR_B)
#define CLRMASK_A (CLR_CMASK << CLR_A)
typedef uint64_t Color;
typedef int16_t ColorComponent;
Color rgba(float r, float g, float b, float a);
Color rgb(float r, float g, float b);
void parse_color(Color clr, float *r, float *g, float *b, float *a);
void parse_color_call(Color clr, void(*func)(float r, float g, float b, float a));
void parse_color_array(Color clr, float array[4]);
Color derive_color(Color src, Color mask, Color mod);
Color multiply_colors(Color c1, Color c2);
Color add_colors(Color c1, Color c2);
Color subtract_colors(Color c1, Color c2);
float color_component(Color clr, unsigned int ofs);
int color_test(void);
#endif

View file

@ -19,13 +19,13 @@ const char* difficulty_name(Difficulty diff) {
}
}
void difficulty_color(Color *c, Difficulty diff) {
Color difficulty_color(Difficulty diff) {
switch(diff) {
case D_Easy: c->r = 0.5; c->g = 1.0; c->b = 0.5; break;
case D_Normal: c->r = 0.5; c->g = 0.5; c->b = 1.0; break;
case D_Hard: c->r = 1.0; c->g = 0.5; c->b = 0.5; break;
case D_Lunatic: c->r = 1.0; c->g = 0.5; c->b = 1.0; break;
case D_Extra: c->r = 0.5; c->g = 1.0; c->b = 1.0; break;
default: c->r = 0.5; c->g = 0.5; c->b = 0.5; break;
case D_Easy: return rgb(0.5, 1.0, 0.5);
case D_Normal: return rgb(0.5, 0.5, 1.0);
case D_Hard: return rgb(1.0, 0.5, 0.5);
case D_Lunatic: return rgb(1.0, 0.5, 1.0);
case D_Extra: return rgb(0.5, 1.0, 1.0);
default: return rgb(0.5, 0.5, 0.5);
}
}

View file

@ -25,6 +25,6 @@ typedef enum {
#define NUM_SELECTABLE_DIFFICULTIES D_Lunatic
const char* difficulty_name(Difficulty diff);
void difficulty_color(Color *c, Difficulty diff);
Color difficulty_color(Difficulty diff);
#endif

View file

@ -46,11 +46,11 @@ void _delete_enemy(void **enemies, void* enemy) {
play_sound("enemydeath");
for(i = 0; i < 10; i++) {
tsrand_fill(2);
create_particle2c("flare", e->pos, NULL, Fade, timeout_linear, 10, (3+afrand(0)*10)*cexp(I*afrand(1)*2*M_PI));
create_particle2c("flare", e->pos, 0, Fade, timeout_linear, 10, (3+afrand(0)*10)*cexp(I*afrand(1)*2*M_PI));
}
create_particle1c("blast", e->pos, NULL, Blast, timeout, 20);
create_particle1c("blast", e->pos, NULL, Blast, timeout, 20);
create_particle2c("blast", e->pos, NULL, GrowFade, timeout, 15,0);
create_particle1c("blast", e->pos, 0, Blast, timeout, 20);
create_particle1c("blast", e->pos, 0, Blast, timeout, 20);
create_particle2c("blast", e->pos, 0, GrowFade, timeout, 15,0);
}
e->logic_rule(enemy, EVENT_DEATH);
del_ref(enemy);
@ -128,7 +128,7 @@ void EnemyFlareShrink(Projectile *p, int t) {
glScalef(s, s, 1);
if(p->clr)
glColor4fv((float *)p->clr);
parse_color_call(p->clr, glColor4f);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
draw_texture_p(0, 0, p->tex);

View file

@ -14,6 +14,7 @@
#include <math.h>
#include "tscomplex.h"
#include "color.h"
#include "resource/audio.h"
#include "resource/bgm.h"

View file

@ -9,7 +9,7 @@
#include "global.h"
#include "list.h"
Laser *create_laser(complex pos, float time, float deathtime, Color *color, LaserPosRule prule, LaserLogicRule lrule, complex a0, complex a1, complex a2, complex a3) {
Laser *create_laser(complex pos, float time, float deathtime, Color color, LaserPosRule prule, LaserLogicRule lrule, complex a0, complex a1, complex a2, complex a3) {
Laser *l = create_element((void **)&global.lasers, sizeof(Laser));
l->birthtime = global.frames;
@ -40,13 +40,14 @@ Laser *create_laser(complex pos, float time, float deathtime, Color *color, Lase
return l;
}
Laser *create_laserline_ab(complex a, complex b, float width, float charge, float dur, Color *clr) {
Laser *create_laserline_ab(complex a, complex b, float width, float charge, float dur, Color clr) {
complex m = (b-a)*0.005;
return create_laser(a, 200, dur, clr, las_linear, static_laser, m, charge + I*width, 0, 0);
}
void draw_laser_curve_instanced(Laser *l) {
static float clr[4];
float t;
int c;
@ -72,7 +73,8 @@ void draw_laser_curve_instanced(Laser *l) {
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glUseProgram(l->shader->prog);
glUniform4fv(uniloc(l->shader, "clr"), 1, (float *)l->color);
parse_color_array(l->color, clr);
glUniform4fv(uniloc(l->shader, "clr"), 1, clr);
glUniform2f(uniloc(l->shader, "pos"), creal(l->pos), cimag(l->pos));
glUniform2f(uniloc(l->shader, "a0"), creal(l->args[0]), cimag(l->args[0]));
@ -98,9 +100,7 @@ void draw_laser_curve(Laser *laser) {
complex last;
glBindTexture(GL_TEXTURE_2D, tex->gltex);
glColor4fv((float *)laser->color);
parse_color_call(laser->color, glColor4f);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
float t = (global.frames - laser->birthtime)*laser->speed - laser->timespan + laser->timeshift;
@ -156,7 +156,6 @@ void _delete_laser(void **lasers, void *laser) {
if(l->lrule)
l->lrule(l, EVENT_DEATH);
free(l->color);
del_ref(laser);
delete_element(lasers, laser);
}

View file

@ -23,7 +23,7 @@ struct Laser {
complex pos;
Color *color;
Color color;
int birthtime;
@ -51,9 +51,9 @@ struct Laser {
#define create_laserline(pos, dir, charge, dur, clr) create_laserline_ab(pos, (pos)+(dir)*VIEWPORT_H*1.4/cabs(dir), cabs(dir), charge, dur, clr)
Laser *create_laserline_ab(complex a, complex b, float width, float charge, float dur, Color *clr);
Laser *create_laserline_ab(complex a, complex b, float width, float charge, float dur, Color clr);
Laser *create_laser(complex pos, float time, float deathtime, Color *color, LaserPosRule prule, LaserLogicRule lrule, complex a0, complex a1, complex a2, complex a3);
Laser *create_laser(complex pos, float time, float deathtime, Color color, LaserPosRule prule, LaserLogicRule lrule, complex a0, complex a1, complex a2, complex a3);
void draw_lasers(void);
void delete_lasers(void);
void process_lasers(void);

View file

@ -72,6 +72,10 @@ int run_tests(void) {
return 1;
}
if(color_test()) {
return 1;
}
return 0;
}

View file

@ -245,7 +245,7 @@ void player_death(Player *plr) {
int i;
for(i = 0; i < 20; i++) {
tsrand_fill(2);
create_particle2c("flare", plr->pos, NULL, Shrink, timeout_linear, 40, (3+afrand(0)*7)*cexp(I*tsrand_a(1)));
create_particle2c("flare", plr->pos, 0, Shrink, timeout_linear, 40, (3+afrand(0)*7)*cexp(I*tsrand_a(1)));
}
create_particle2c("blast", plr->pos, rgb(1,0.5,0.3), GrowFade, timeout, 35, 2.4);
plr->deathtime = global.frames + DEATHBOMB_TIME;
@ -425,6 +425,6 @@ void player_graze(Player *plr, complex pos, int pts) {
int i = 0; for(i = 0; i < 5; ++i) {
tsrand_fill(3);
create_particle2c("flare", pos, NULL, Shrink, timeout_linear, 5 + 5 * afrand(2), (1+afrand(0)*5)*cexp(I*tsrand_a(1)));
create_particle2c("flare", pos, 0, Shrink, timeout_linear, 5 + 5 * afrand(2), (1+afrand(0)*5)*cexp(I*tsrand_a(1)));
}
}

View file

@ -99,7 +99,7 @@ int youmu_slash(Enemy *e, int t) {
FROM_TO(30, 60, 10) {
tsrand_fill(3);
create_particle1c("youmu_slice", VIEWPORT_W/2.0 - 150 + 100*_i + VIEWPORT_H/2.0*I - 10-10.0*I + 20*afrand(0)+20.0*I*afrand(1), NULL, Slice, timeout, 200)->angle = -10.0+20.0*afrand(2);
create_particle1c("youmu_slice", VIEWPORT_W/2.0 - 150 + 100*_i + VIEWPORT_H/2.0*I - 10-10.0*I + 20*afrand(0)+20.0*I*afrand(1), 0, Slice, timeout, 200)->angle = -10.0+20.0*afrand(2);
}
FROM_TO(40,200,1)
@ -124,7 +124,7 @@ int youmu_slash(Enemy *e, int t) {
void YoumuOppositeMyon(Enemy *e, int t) {
complex pos = e->pos;
create_particle2c("flare", pos, NULL, Shrink, timeout, 10, -e->pos+10.0*I);
create_particle2c("flare", pos, 0, Shrink, timeout, 10, -e->pos+10.0*I);
}
int youmu_opposite_myon(Enemy *e, int t) {
@ -174,11 +174,11 @@ int youmu_opposite_myon(Enemy *e, int t) {
if(plr->power >= 300) {
a = 13;
create_projectile1c("hghost", e->pos, NULL, linear, -21*cexp(I*(carg(-e->pos0)+0.1)))->type = PlrProj+45;
create_projectile1c("hghost", e->pos, NULL, linear, -21*cexp(I*(carg(-e->pos0)-0.1)))->type = PlrProj+45;
create_projectile1c("hghost", e->pos, 0, linear, -21*cexp(I*(carg(-e->pos0)+0.1)))->type = PlrProj+45;
create_projectile1c("hghost", e->pos, 0, linear, -21*cexp(I*(carg(-e->pos0)-0.1)))->type = PlrProj+45;
}
create_projectile1c("hghost", e->pos, NULL, linear, -21*cexp(I*carg(-e->pos0)))->type = PlrProj+(60+a*(plr->power/100));
create_projectile1c("hghost", e->pos, 0, linear, -21*cexp(I*carg(-e->pos0)))->type = PlrProj+(60+a*(plr->power/100));
}
return 1;
@ -200,7 +200,7 @@ int youmu_split(Enemy *e, int t) {
FROM_TO(100,170,10) {
tsrand_fill(3);
create_particle1c("youmu_slice", VIEWPORT_W/2.0 + VIEWPORT_H/2.0*I - 200-200.0*I + 400*afrand(0)+400.0*I*afrand(1), NULL, Slice, timeout, 100-_i)->angle = 360.0*afrand(2);
create_particle1c("youmu_slice", VIEWPORT_W/2.0 + VIEWPORT_H/2.0*I - 200-200.0*I + 400*afrand(0)+400.0*I*afrand(1), 0, Slice, timeout, 100-_i)->angle = 360.0*afrand(2);
}
@ -223,8 +223,8 @@ void youmu_shot(Player *plr) {
play_sound("generic_shot");
if(!(global.frames % 6)) {
create_projectile1c("youmu", plr->pos + 10 - I*20, NULL, linear, -20.0*I)->type = PlrProj+120;
create_projectile1c("youmu", plr->pos - 10 - I*20, NULL, linear, -20.0*I)->type = PlrProj+120;
create_projectile1c("youmu", plr->pos + 10 - I*20, 0, linear, -20.0*I)->type = PlrProj+120;
create_projectile1c("youmu", plr->pos - 10 - I*20, 0, linear, -20.0*I)->type = PlrProj+120;
}
if(plr->shot == YoumuHoming) {
@ -237,13 +237,13 @@ void youmu_shot(Player *plr) {
if(ref == -1)
ref = add_ref(NULL);
create_projectile2c("youhoming", plr->pos, NULL, youmu_homing, -3.0*I, ref)->type = PlrProj+(450+225*(plr->power/100));
create_projectile2c("youhoming", plr->pos, 0, youmu_homing, -3.0*I, ref)->type = PlrProj+(450+225*(plr->power/100));
}
if(!plr->focus && !(global.frames % (int)round(8 - (plr->power / 100.0) * 1.3))) {
create_projectile2c("hghost", plr->pos, NULL, accelerated, 2-10.0*I, -0.4*I)->type = PlrProj+27;
create_projectile2c("hghost", plr->pos, NULL, accelerated, -10.0*I, -0.4*I)->type = PlrProj+27;
create_projectile2c("hghost", plr->pos, NULL, accelerated, -2-10.0*I, -0.4*I)->type = PlrProj+27;
create_projectile2c("hghost", plr->pos, 0, accelerated, 2-10.0*I, -0.4*I)->type = PlrProj+27;
create_projectile2c("hghost", plr->pos, 0, accelerated, -10.0*I, -0.4*I)->type = PlrProj+27;
create_projectile2c("hghost", plr->pos, 0, accelerated, -2-10.0*I, -0.4*I)->type = PlrProj+27;
}
}
}
@ -309,13 +309,13 @@ int mari_laser(Projectile *p, int t) {
int marisa_laser_slave(Enemy *e, int t) {
if(global.plr.fire && global.frames - global.plr.recovery >= 0 && global.plr.deathtime >= -1) {
if(!(global.frames % 4))
create_projectile_p(&global.projs, get_tex("proj/marilaser"), 0, NULL, MariLaser, mari_laser, 0, add_ref(e),e->args[2],0)->type = PlrProj+e->args[1]*4;
create_projectile_p(&global.projs, get_tex("proj/marilaser"), 0, 0, MariLaser, mari_laser, 0, add_ref(e),e->args[2],0)->type = PlrProj+e->args[1]*4;
if(!(global.frames % 3)) {
float s = 0.5 + 0.3*sin(global.frames/7.0);
create_particle3c("marilaser_part0", 0, rgb(1-s,0.5,s), PartDraw, mari_laser, 0, add_ref(e), e->args[2]);
}
create_particle1c("lasercurve", e->pos, NULL, Fade, timeout, 4)->type = PlrProj;
create_particle1c("lasercurve", e->pos, 0, Fade, timeout, 4)->type = PlrProj;
}
e->pos = global.plr.pos + (1 - abs(global.plr.focus)/30.0)*e->pos0 + (abs(global.plr.focus)/30.0)*e->args[0];
@ -423,12 +423,12 @@ void MariStarTrail(Projectile *p, int t) {
void MariStarBomb(Projectile *p, int t) {
MariStar(p, t);
create_particle1c("maristar_orbit", p->pos, NULL, GrowFadeAdd, timeout, 40);
create_particle1c("maristar_orbit", p->pos, 0, GrowFadeAdd, timeout, 40);
}
int marisa_star_projectile(Projectile *p, int t) {
int r = accelerated(p, t);
create_projectile_p(&global.particles, get_tex("proj/maristar"), p->pos, NULL, MariStarTrail, timeout, 10, 0, 0, 0)->type = Particle;
create_projectile_p(&global.particles, get_tex("proj/maristar"), p->pos, 0, MariStarTrail, timeout, 10, 0, 0, 0)->type = Particle;
return r;
}
@ -437,7 +437,7 @@ int marisa_star_slave(Enemy *e, int t) {
if(global.plr.fire && global.frames - global.plr.recovery >= 0 && global.plr.deathtime >= -1) {
if(!(global.frames % 20))
create_projectile_p(&global.projs, get_tex("proj/maristar"), e->pos, NULL, MariStar, marisa_star_projectile, e->args[1] * 2 * (1 - 1.5 * focus), e->args[2], 0, 0)->type = PlrProj+e->args[3]*20;
create_projectile_p(&global.projs, get_tex("proj/maristar"), e->pos, 0, MariStar, marisa_star_projectile, e->args[1] * 2 * (1 - 1.5 * focus), e->args[2], 0, 0)->type = PlrProj+e->args[3]*20;
}
e->pos = global.plr.pos + (1 - focus)*e->pos0 + focus*e->args[0];
@ -472,8 +472,8 @@ void marisa_shot(Player *plr) {
play_sound("generic_shot");
if(!(global.frames % 6)) {
create_projectile1c("marisa", plr->pos + 10 - 15.0*I, NULL, linear, -20.0*I)->type = PlrProj+150;
create_projectile1c("marisa", plr->pos - 10 - 15.0*I, NULL, linear, -20.0*I)->type = PlrProj+150;
create_projectile1c("marisa", plr->pos + 10 - 15.0*I, 0, linear, -20.0*I)->type = PlrProj+150;
create_projectile1c("marisa", plr->pos - 10 - 15.0*I, 0, linear, -20.0*I)->type = PlrProj+150;
}
}
}
@ -490,7 +490,7 @@ void marisa_bomb(Player *plr) {
for(i = 0; i < 20; i++) {
r = frand()*40 + 100;
phi = frand()*2*M_PI;
create_particle1c("maristar_orbit", plr->pos + r*cexp(I*phi), NULL, MariStarBomb, marisa_star_orbit, I*r*cexp(I*(phi+frand()*0.5))/10);
create_particle1c("maristar_orbit", plr->pos + r*cexp(I*phi), 0, MariStarBomb, marisa_star_orbit, I*r*cexp(I*(phi+frand()*0.5))/10);
}
break;
default:

View file

@ -12,18 +12,18 @@
#include "list.h"
#include "vbo.h"
Projectile *create_particle4c(char *name, complex pos, Color *clr, ProjDRule draw, ProjRule rule, complex a1, complex a2, complex a3, complex a4) {
Projectile *create_particle4c(char *name, complex pos, Color clr, ProjDRule draw, ProjRule rule, complex a1, complex a2, complex a3, complex a4) {
Projectile *p = create_projectile_p(&global.particles, prefix_get_tex(name, "part/"), pos, clr, draw, rule, a1, a2, a3, a4);
p->type = Particle;
return p;
}
Projectile *create_projectile4c(char *name, complex pos, Color *clr, ProjRule rule, complex a1, complex a2, complex a3, complex a4) {
Projectile *create_projectile4c(char *name, complex pos, Color clr, ProjRule rule, complex a1, complex a2, complex a3, complex a4) {
return create_projectile_p(&global.projs, prefix_get_tex(name, "proj/"), pos, clr, ProjDraw, rule, a1, a2, a3, a4);
}
Projectile *create_projectile_p(Projectile **dest, Texture *tex, complex pos, Color *clr,
Projectile *create_projectile_p(Projectile **dest, Texture *tex, complex pos, Color clr,
ProjDRule draw, ProjRule rule, complex a1, complex a2, complex a3, complex a4) {
Projectile *p, *e, **d;
@ -61,7 +61,6 @@ void _delete_projectile(void **projs, void *proj) {
Projectile *p = proj;
p->rule(p, EVENT_DEATH);
free(p->clr);
del_ref(proj);
delete_element(projs, proj);
}
@ -132,7 +131,7 @@ void process_projectiles(Projectile **projs, bool collision) {
if(proj->type == DeadProj && killed < 5) {
killed++;
action = ACTION_DESTROY;
create_particle1c("flare", proj->pos, NULL, Fade, timeout, 30);
create_particle1c("flare", proj->pos, 0, Fade, timeout, 30);
create_item(proj->pos, 0, BPoint)->auto_collect = 10;
}
@ -140,12 +139,7 @@ void process_projectiles(Projectile **projs, bool collision) {
col = collision_projectile(proj);
if(col && proj->type != Particle) {
Color *clr = NULL;
if(proj->clr) {
clr = malloc(sizeof(Color));
memcpy(clr, proj->clr, sizeof(Color));
}
create_projectile_p(&global.particles, proj->tex, proj->pos, clr, DeathShrink, timeout_linear, 10, 5*cexp(proj->angle*I), 0, 0);
create_projectile_p(&global.particles, proj->tex, proj->pos, proj->clr, DeathShrink, timeout_linear, 10, 5*cexp(proj->angle*I), 0, 0);
}
if(col == 1 && global.frames - abs(global.plr.recovery) >= 0)
@ -202,19 +196,20 @@ int asymptotic(Projectile *p, int t) { // v = a[0]*(a[1] + 1); a[1] -> 0
}
void _ProjDraw(Projectile *proj, int t) {
if(proj->clr != NULL && !config_get_int(CONFIG_NO_SHADER)) {
if(proj->clr && !config_get_int(CONFIG_NO_SHADER)) {
static GLfloat clr[4];
Shader *shader = get_shader("bullet_color");
glUseProgram(shader->prog);
glUniform4fv(uniloc(shader, "color"), 1, (GLfloat *)proj->clr);
parse_color_array(proj->clr, clr);
glUniform4fv(uniloc(shader, "color"), 1, clr);
}
if(proj->clr != NULL && config_get_int(CONFIG_NO_SHADER))
if(!proj->clr && config_get_int(CONFIG_NO_SHADER))
glColor3f(0,0,0);
draw_texture_p(0,0, proj->tex);
if(proj->clr != NULL && config_get_int(CONFIG_NO_SHADER))
if(proj->clr && config_get_int(CONFIG_NO_SHADER))
glColor3f(1,1,1);
if(!config_get_int(CONFIG_NO_SHADER))
@ -256,8 +251,9 @@ void PartDraw(Projectile *proj, int t) {
glTranslatef(creal(proj->pos), cimag(proj->pos), 0);
glRotatef(proj->angle*180/M_PI+90, 0, 0, 1);
if(proj->clr)
glColor4fv((float *)proj->clr);
if(proj->clr) {
parse_color_call(proj->clr, glColor4f);
}
draw_texture_p(0,0, proj->tex);
@ -337,7 +333,7 @@ void GrowFade(Projectile *p, int t) {
glScalef(s, s, 1);
if(p->clr)
glColor4f(p->clr->r,p->clr->g,p->clr->b,1-t/p->args[0]);
parse_color_call(derive_color(p->clr, CLRMASK_A, rgba(0,0,0,1-t/p->args[0])), glColor4f);
else if(t/p->args[0] != 0)
glColor4f(1,1,1,1-t/p->args[0]);
@ -359,7 +355,7 @@ void Fade(Projectile *p, int t) {
void FadeAdd(Projectile *p, int t) {
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glColor4f(p->clr->r,p->clr->g,p->clr->b, 1.0 - (float)t/p->args[0]);
parse_color_call(derive_color(p->clr, CLRMASK_A, rgba(0,0,0, 1.0 - (float)t/p->args[0])), glColor4f);
glPushMatrix();
glTranslatef(creal(p->pos), cimag(p->pos), 0);
glRotatef(180/M_PI*p->angle+90, 0, 0, 1);
@ -402,8 +398,9 @@ void Petal(Projectile *p, int t) {
glTranslatef(creal(p->pos), cimag(p->pos),0);
glRotatef(t*4.0 + cimag(p->args[3]), x, y, z);
if(p->clr)
glColor4fv((float *)p->clr);
if(p->clr) {
parse_color_call(p->clr, glColor4f);
}
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
draw_texture_p(0,0, p->tex);

View file

@ -10,6 +10,7 @@
#include "tscomplex.h"
#include "resource/texture.h"
#include "color.h"
#include <stdbool.h>
@ -45,7 +46,7 @@ typedef struct Projectile {
ProjType type;
Color *clr;
Color clr;
complex args[RULE_ARGC];
int grazed;
@ -59,9 +60,9 @@ typedef struct Projectile {
#define create_projectile2c(n,p,c,r,a1,a2) create_projectile4c(n,p,c,r,a1,a2,0,0)
#define create_projectile1c(n,p,c,r,a1) create_projectile4c(n,p,c,r,a1,0,0,0)
Projectile *create_particle4c(char *name, complex pos, Color *clr, ProjDRule draw, ProjRule rule, complex a1, complex a2, complex a3, complex a4);
Projectile *create_projectile4c(char *name, complex pos, Color *clr, ProjRule rule, complex a1, complex a2, complex a3, complex a4);
Projectile *create_projectile_p(Projectile **dest, Texture *tex, complex pos, Color *clr, ProjDRule draw, ProjRule rule, complex a1, complex a2, complex a3, complex a4);
Projectile *create_particle4c(char *name, complex pos, Color clr, ProjDRule draw, ProjRule rule, complex a1, complex a2, complex a3, complex a4);
Projectile *create_projectile4c(char *name, complex pos, Color clr, ProjRule rule, complex a1, complex a2, complex a3, complex a4);
Projectile *create_projectile_p(Projectile **dest, Texture *tex, complex pos, Color clr, ProjDRule draw, ProjRule rule, complex a1, complex a2, complex a3, complex a4);
void delete_projectile(Projectile **dest, Projectile *proj);
void delete_projectiles(Projectile **dest);
void draw_projectiles(Projectile *projs);

View file

@ -10,7 +10,6 @@
#include <SDL.h>
#include "taiseigl.h"
#include "color.h"
typedef struct Texture Texture;

View file

@ -24,7 +24,7 @@
static size_t numstages = 0;
StageInfo *stages = NULL;
static void add_stage(uint16_t id, StageProcs *procs, StageType type, const char *title, const char *subtitle, AttackInfo *spell, Difficulty diff, Color *titleclr, Color *bosstitleclr) {
static void add_stage(uint16_t id, StageProcs *procs, StageType type, const char *title, const char *subtitle, AttackInfo *spell, Difficulty diff, Color titleclr, Color bosstitleclr) {
++numstages;
stages = realloc(stages, numstages * sizeof(StageInfo));
StageInfo *stg = stages + (numstages - 1);
@ -37,17 +37,8 @@ static void add_stage(uint16_t id, StageProcs *procs, StageType type, const char
stralloc(&stg->subtitle, subtitle);
stg->spell = spell;
stg->difficulty = diff;
if(titleclr) {
memcpy(&stg->titleclr, titleclr, sizeof(Color));
}
if(bosstitleclr) {
memcpy(&stg->bosstitleclr, titleclr, sizeof(Color));
}
free(titleclr);
free(bosstitleclr);
stg->titleclr = titleclr;
stg->bosstitleclr = titleclr;
#ifdef DEBUG
if(title && subtitle) {
@ -57,7 +48,7 @@ static void add_stage(uint16_t id, StageProcs *procs, StageType type, const char
}
static void end_stages() {
add_stage(0, NULL, 0, NULL, NULL, NULL, 0, NULL, NULL);
add_stage(0, NULL, 0, NULL, NULL, NULL, 0, 0, 0);
}
void stage_init_array(void) {
@ -93,7 +84,7 @@ void stage_init_array(void) {
strcat(subtitle, " ~ ");
strcat(subtitle, postfix);
add_stage(id, s->procs->spellpractice_procs, STAGE_SPELL, title, subtitle, a, diff, NULL, NULL);
add_stage(id, s->procs->spellpractice_procs, STAGE_SPELL, title, subtitle, a, diff, 0, 0);
s = stages + i; // stages just got realloc'd, so we must update the pointer
}
}
@ -357,9 +348,7 @@ void draw_hud(void) {
glTranslatef((SCREEN_W - 615) * 0.25, 20, 0);
glScalef(0.6, 0.6, 0);
Color clr;
difficulty_color(&clr, global.diff);
glColor4f(clr.r, clr.g, clr.b, 0.7f);
parse_color_call(derive_color(difficulty_color(global.diff), CLRMASK_A, rgba(0, 0, 0, 0.7f)), glColor4f);
diff = difficulty_name(global.diff);
draw_text(AL_Center, 1, 1, diff, _fonts.mainmenu);
@ -560,10 +549,13 @@ static void apply_bg_shaders(ShaderRule *shaderrules) {
glUniform1f(uniloc(shader, "blur_rad"), 0.2+0.025*sin(global.frames/15.0));
glUniform1f(uniloc(shader, "rad"), 0.24);
glUniform1f(uniloc(shader, "ratio"), (float)resources.fbg[fbonum].nh/resources.fbg[fbonum].nw);
if(global.boss->zoomcolor)
glUniform4fv(uniloc(shader, "color"), 1, (float *)global.boss->zoomcolor);
else
if(global.boss->zoomcolor) {
static float clr[4];
parse_color_array(global.boss->zoomcolor, clr);
glUniform4fv(uniloc(shader, "color"), 1, clr);
} else {
glUniform4f(uniloc(shader, "color"), 0.1, 0.2, 0.3, 1);
}
}
@ -788,7 +780,7 @@ void stage_loop(StageInfo *stage) {
free_all_refs();
}
static void draw_title(int t, StageInfo *info, Alignment al, int x, int y, const char *text, TTF_Font *font, Color *color) {
static void draw_title(int t, Alignment al, int x, int y, const char *text, TTF_Font *font, Color color) {
int i;
float f = 0;
if(t < 30 || t > 220)
@ -800,17 +792,20 @@ static void draw_title(int t, StageInfo *info, Alignment al, int x, int y, const
}
if(!config_get_int(CONFIG_NO_SHADER)) {
float clr[4];
parse_color_array(color, clr);
Shader *sha = get_shader("stagetitle");
glUseProgram(sha->prog);
glUniform1i(uniloc(sha, "trans"), 1);
glUniform1f(uniloc(sha, "t"), 1.0-f);
glUniform3fv(uniloc(sha, "color"), 1, (float *)color);
glUniform3fv(uniloc(sha, "color"), 1, clr);
glActiveTexture(GL_TEXTURE0 + 1);
glBindTexture(GL_TEXTURE_2D, get_tex("titletransition")->gltex);
glActiveTexture(GL_TEXTURE0);
} else {
glColor4f(info->titleclr.r,info->titleclr.g,info->titleclr.b,1.0-f);
parse_color_call(derive_color(color, CLRMASK_A, rgba(0, 0, 0, 1.0 - f)), glColor4f);
}
draw_text(al, x, y, text, font);
@ -822,12 +817,12 @@ static void draw_title(int t, StageInfo *info, Alignment al, int x, int y, const
static void draw_stage_title(StageInfo *info) {
int t = global.stageuiframes;
draw_title(t, info, AL_Center, VIEWPORT_W/2, VIEWPORT_H/2-40, info->title, _fonts.mainmenu, &info->titleclr);
draw_title(t, info, AL_Center, VIEWPORT_W/2, VIEWPORT_H/2, info->subtitle, _fonts.standard, &info->titleclr);
draw_title(t, AL_Center, VIEWPORT_W/2, VIEWPORT_H/2-40, info->title, _fonts.mainmenu, info->titleclr);
draw_title(t, AL_Center, VIEWPORT_W/2, VIEWPORT_H/2, info->subtitle, _fonts.standard, info->titleclr);
if ((current_bgm.title != NULL) && (current_bgm.started_at >= 0))
{
draw_title(t - current_bgm.started_at, info, AL_Right, VIEWPORT_W-15, VIEWPORT_H-35, current_bgm.title, _fonts.standard,
current_bgm.isboss ? &info->bosstitleclr : &info->titleclr);
draw_title(t - current_bgm.started_at, AL_Right, VIEWPORT_W-15, VIEWPORT_H-35, current_bgm.title, _fonts.standard,
current_bgm.isboss ? info->bosstitleclr : info->titleclr);
}
}

View file

@ -165,7 +165,6 @@ int cirno_pfreeze_frogs(Projectile *p, int t) {
if(boss_t < 110)
linear(p, t);
else if(boss_t == 110) {
free(p->clr);
p->clr = rgb(0.7,0.7,0.7);
}

View file

@ -282,10 +282,12 @@ int stage3_mid_a0_proj(Projectile *p, int time) {
int cnt = 2 + global.diff, i;
for(i = 0; i < cnt; ++i) {
tsrand_fill(2);
create_particle3c("lasercurve", 0, rgb(max(0.3, 1.0 - p->clr->r), p->clr->g, p->clr->b), EnemyFlareShrink, enemy_flare, 100, cexp(I*(M_PI*anfrand(0))) * (1 + afrand(1)), add_ref(p));
Color clr = derive_color(p->clr, CLRMASK_R, rgb(max(0.3, 1.0 - color_component(p->clr, CLR_R)), 0, 0));
create_particle3c("lasercurve", 0, clr, EnemyFlareShrink, enemy_flare, 100, cexp(I*(M_PI*anfrand(0))) * (1 + afrand(1)), add_ref(p));
int jcnt = 1 + (global.diff > D_Normal), j;
for(j = 0; j < jcnt; ++j) create_projectile1c("thickrice", p->pos, p->clr->r == 1.0? rgb(1.0, 0.3, 0.3) : rgb(0.3, 0.3, 1.0), accelerated,
for(j = 0; j < jcnt; ++j) create_projectile1c("thickrice", p->pos, color_component(p->clr, CLR_R) == 1.0? rgb(1.0, 0.3, 0.3) : rgb(0.3, 0.3, 1.0), accelerated,
0
-cexp(I*(i*2*M_PI/cnt + global.frames / 15.0)) * (1.0 + 0.1 * j)
); //->draw = global.diff > D_Hard? ProjDrawAdd : ProjDraw;
@ -510,7 +512,7 @@ void stage3_boss_a1_slave_part(Projectile *p, int t) {
Texture *tex = p->tex;
glBindTexture(GL_TEXTURE_2D, tex->gltex);
float b = 1 - t / p->args[0];
glColor4f(p->clr->r*b, p->clr->g*b, p->clr->b*b, 1);
parse_color_call(multiply_colors(p->clr, rgb(b, b, b)), glColor4f);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glPushMatrix();
@ -673,8 +675,8 @@ void stage3_boss_a3(Boss *boss, int time) {
float b = 0.5;
Color *c1;
Color *c2;
Color c1;
Color c2;
if(_i % 2) {
c1 = rgb(1.0, 1.0, b);

View file

@ -407,7 +407,7 @@ Boss *create_kurumi_mid(void) {
int splitcard(Projectile *p, int t) {
if(t == creal(p->args[2])) {
p->args[0] += p->args[3];
p->clr->b = -p->clr->b;
p->clr = derive_color(p->clr, CLRMASK_B, rgb(0, 0, -color_component(p->clr, CLR_B)));
}
return asymptotic(p, t);
@ -497,7 +497,7 @@ int aniwall_bullet(Projectile *p, int t) {
p->pos += p->args[0];
}
p->clr->r = cimag(p->pos)/VIEWPORT_H;
p->clr = derive_color(p->clr, CLRMASK_R, rgb(cimag(p->pos)/VIEWPORT_H, 0, 0));
return 1;
}

View file

@ -182,7 +182,7 @@ int scythe_mid(Enemy *e, int t) {
}
void Scythe(Enemy *e, int t) {
Projectile *p = create_projectile_p(&global.particles, get_tex("stage6/scythe"), e->pos, NULL, ScaleFade, timeout, 8, e->args[2], 0, 0);
Projectile *p = create_projectile_p(&global.particles, get_tex("stage6/scythe"), e->pos, 0, ScaleFade, timeout, 8, e->args[2], 0, 0);
p->type = Particle;
p->angle = creal(e->args[1]);
@ -316,7 +316,7 @@ int scythe_newton(Enemy *e, int t) {
for(p = global.projs; p; p = p->next) {
if(p->type == FairyProj && cabs(p->pos-e->pos) < 50) {
p->args[1] = 0.01*global.diff*cexp(I*f);
p->clr->r = frand();
p->clr = derive_color(p->clr, CLRMASK_R, rgba(frand(), 0, 0, 0));
}
}
}
@ -666,7 +666,7 @@ int ricci_proj(Projectile *p, int t) {
}
p->angle = carg(p->args[0]);
p->clr->b = cabs(p->args[0])*0.5;
p->clr = derive_color(p->clr, CLRMASK_B, rgb(0, 0, cabs(p->args[0])*0.5));
return 1;
}
@ -862,10 +862,7 @@ int theory_proj(Projectile *p, int t) {
break;
}
p->clr->r = cos(p->angle);
p->clr->g = sin(p->angle);
p->clr->b = cos(p->angle+2.1);
p->clr = rgb(cos(p->angle), sin(p->angle), cos(p->angle+2.1));
p->args[1] += I;
}