mirror of https://github.com/snes9xgit/snes9x.git
GTK: Oops. Add particle files.
This commit is contained in:
parent
19f7423f42
commit
0258422be8
|
@ -0,0 +1,192 @@
|
|||
#include "background_particles.h"
|
||||
#include <cstring>
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <random>
|
||||
|
||||
static const double pi = 3.141592;
|
||||
|
||||
namespace Background
|
||||
{
|
||||
|
||||
Particles::Particles(enum Mode mode)
|
||||
{
|
||||
this->mode = Invalid;
|
||||
setmode(mode);
|
||||
}
|
||||
|
||||
Particles::~Particles()
|
||||
{
|
||||
}
|
||||
|
||||
void Particles::setmode(enum Mode mode)
|
||||
{
|
||||
if (mode == this->mode)
|
||||
return;
|
||||
std::random_device device;
|
||||
mt.seed(device());
|
||||
output.resize(256 * 224 * 2);
|
||||
gameimage.resize(256 * 224 * 2);
|
||||
|
||||
uint16_t r, g, b;
|
||||
if (mode == Snow)
|
||||
{
|
||||
r = 0; g = 2; b = 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
r = 0; g = 0; b = 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 256 * 224; i++)
|
||||
{
|
||||
output[i] = (r << 11) | (g << 6) | (b);
|
||||
}
|
||||
particles.clear();
|
||||
|
||||
this->mode = mode;
|
||||
std::uniform_real_distribution<double> real(-0.8, 0.8);
|
||||
wind = real(mt);
|
||||
|
||||
for (int l = 0; l < 32; l++)
|
||||
{
|
||||
int mixr = r + (l / 31.0) * (31 - r);
|
||||
int mixg = g + (l / 31.0) * (31 - g);
|
||||
int mixb = b + (l / 31.0) * (31 - b);
|
||||
color_table[l] = (mixr << 11) | (mixg << 6) | mixb;
|
||||
}
|
||||
}
|
||||
|
||||
void Particles::copyto(uint16_t *dst, int pitch)
|
||||
{
|
||||
for (int y = 0; y < 224; y++)
|
||||
{
|
||||
memcpy((uint8_t *)dst + y * pitch, &output[y * 256], 512);
|
||||
}
|
||||
}
|
||||
|
||||
void Particles::set_game_image(uint16_t *src, int pitch)
|
||||
{
|
||||
for (int y = 0; y < 224; y++)
|
||||
memcpy(&gameimage[y * 256], &src[y * pitch / 2], 512);
|
||||
}
|
||||
|
||||
void Particles::advance()
|
||||
{
|
||||
if (mode == Snow)
|
||||
advance_snow();
|
||||
else
|
||||
advance_starfield();
|
||||
}
|
||||
|
||||
inline void Particles::setpixel(int x, int y, uint16_t l)
|
||||
{
|
||||
output[x + (y << 8)] = color_table[l];
|
||||
}
|
||||
|
||||
void Particles::advance_starfield()
|
||||
{
|
||||
rate = 0.5;
|
||||
|
||||
std::uniform_real_distribution<double> realrand(0.0, 1.0);
|
||||
if (realrand(mt) <= rate)
|
||||
{
|
||||
Particle pt;
|
||||
|
||||
double angle = realrand(mt) * 2 * pi;
|
||||
pt.dx = cos(angle);
|
||||
pt.dy = sin(angle) * 0.7;
|
||||
pt.x = 128.5 + pt.dx * 5.0;
|
||||
pt.y = 112.5 + pt.dy * 5.0;
|
||||
pt.intensity = 0;
|
||||
|
||||
particles.push_back(pt);
|
||||
}
|
||||
|
||||
for (auto p = particles.begin(); p != particles.end(); p++)
|
||||
{
|
||||
setpixel(p->x - 0.5, p->y - 0.5, 0);
|
||||
setpixel(p->x + 0.5, p->y + 0.5, 0);
|
||||
setpixel(p->x + 0.5, p->y - 0.5, 0);
|
||||
setpixel(p->x - 0.5, p->y + 0.5, 0);
|
||||
|
||||
p->x += p->dx;
|
||||
p->y += p->dy;
|
||||
|
||||
if ((int)p->x < 1 || (int)p->x > 255 || (int)p->y < 1 || (int)p->y > 223)
|
||||
{
|
||||
p = particles.erase(p);
|
||||
continue;
|
||||
}
|
||||
|
||||
p->intensity = (p->intensity + 1);
|
||||
if (p->intensity > 63)
|
||||
p->intensity = 63;
|
||||
|
||||
uint16_t lum = p->intensity >> 1;
|
||||
|
||||
// primitive bilinear filter effect
|
||||
double dx = p->x - 0.5;
|
||||
dx = dx - floor(dx);
|
||||
double dy = p->y - 0.5;
|
||||
dy = dy - floor(dy);
|
||||
|
||||
uint16_t cul = (1.0 - dx) * (1.0 - dy) * lum;
|
||||
uint16_t cur = (dx) * (1.0 - dy) * lum;
|
||||
uint16_t cll = (1.0 - dx) * (dy)*lum;
|
||||
uint16_t clr = (dx) * (dy)*lum;
|
||||
|
||||
setpixel(p->x - 0.5, p->y - 0.5, cul);
|
||||
setpixel(p->x + 0.5, p->y - 0.5, cur);
|
||||
setpixel(p->x - 0.5, p->y + 0.5, cll);
|
||||
setpixel(p->x + 0.5, p->y + 0.5, clr);
|
||||
}
|
||||
}
|
||||
|
||||
void Particles::advance_snow()
|
||||
{
|
||||
rate = 1.0;
|
||||
|
||||
std::uniform_real_distribution<double> realrand;
|
||||
|
||||
realrand = std::uniform_real_distribution<double>(-0.01, std::nextafter(0.01, 1.0));
|
||||
wind += realrand(mt);
|
||||
|
||||
if (wind < -0.8)
|
||||
wind = -0.8;
|
||||
if (wind > 0.8)
|
||||
wind = 0.8;
|
||||
|
||||
for (double new_snowflakes = rate; new_snowflakes >= 1.0; new_snowflakes -= 1.0)
|
||||
{
|
||||
Particle pt;
|
||||
|
||||
realrand = std::uniform_real_distribution<double>(0.0, 1.0);
|
||||
pt.x = ((wind + 0.8) / 1.6) * -192.0 + realrand(mt) * 384.0;
|
||||
pt.y = 0.0;
|
||||
pt.dx = 0.0;
|
||||
pt.dy = 0.6 + (realrand(mt) * 0.8);
|
||||
std::uniform_int_distribution<int> intrand(8, 31);
|
||||
pt.intensity = intrand(mt);
|
||||
|
||||
particles.push_back(pt);
|
||||
}
|
||||
|
||||
for (auto p = particles.begin(); p != particles.end(); p++)
|
||||
{
|
||||
if (p->x > 0.0 && p->x < 256.0)
|
||||
setpixel(p->x, p->y, 0);
|
||||
|
||||
p->x += wind;
|
||||
p->y += p->dy;
|
||||
|
||||
if ((int)p->y > 223)
|
||||
{
|
||||
p = particles.erase(p);
|
||||
}
|
||||
else if (p->x > 0.0 && p->x < 256.0)
|
||||
setpixel(p->x, p->y, p->intensity);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Background
|
|
@ -0,0 +1,52 @@
|
|||
#pragma once
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <cstdint>
|
||||
#include <random>
|
||||
|
||||
namespace Background
|
||||
{
|
||||
|
||||
class Particles
|
||||
{
|
||||
public:
|
||||
double rate = 0.5;
|
||||
|
||||
enum Mode
|
||||
{
|
||||
Stars,
|
||||
Snow,
|
||||
Invalid
|
||||
};
|
||||
|
||||
struct Particle
|
||||
{
|
||||
double x, y, dx, dy;
|
||||
unsigned int intensity;
|
||||
};
|
||||
|
||||
Particles(enum Mode = Stars);
|
||||
~Particles();
|
||||
void advance();
|
||||
void copyto(uint16_t *dst, int pitch);
|
||||
enum Mode getmode();
|
||||
void setmode(enum Mode);
|
||||
void set_game_image(uint16_t *src, int pitch);
|
||||
|
||||
std::vector<uint16_t> output;
|
||||
|
||||
private:
|
||||
inline void setpixel(int x, int y, uint16_t l);
|
||||
void advance_snow();
|
||||
void advance_starfield();
|
||||
|
||||
std::minstd_rand mt;
|
||||
std::uniform_real_distribution<double> dis;
|
||||
std::vector<uint16_t> gameimage;
|
||||
std::list<Particle> particles;
|
||||
enum Mode mode;
|
||||
double wind;
|
||||
uint16_t color_table[32];
|
||||
};
|
||||
|
||||
} // namespace Background
|
Loading…
Reference in New Issue