Jump to content

  • Log In with Google      Sign In   
  • Create Account


Coding horror experiment in C++

  • You cannot reply to this topic
52 replies to this topic

#21 slicer4ever   Crossbones+   -  Reputation: 3499

Like
3Likes
Like

Posted 03 November 2013 - 03:20 PM

ah, that's great fuzzy!

video:


i'd just say we should have the particles spawn behind the ghosts/people, rather than over them imo.
Check out https://www.facebook.com/LiquidGames for some great games made by me on the Playstation Mobile market.

Sponsor:

#22 Phil123   Members   -  Reputation: 645

Like
0Likes
Like

Posted 03 November 2013 - 08:21 PM

I have to say, despite the intentional coding horror, this is looking pretty damn neat.



#23 rip-off   Moderators   -  Reputation: 8120

Like
3Likes
Like

Posted 04 November 2013 - 04:36 PM

Ok, trying to make a relatively small change and I'm running into an error: "post_too_long". I'm going to have to exclude the cool little dude sprite (sorry riuthamus!), because it really inflates the source and so far hasn't been integrated into the game. The alternative would be to either end the experiment or to amend the rules to allow out-of-line resources.

 

Ghosts now lose interest in stationary mice:


#include <SFML/System.hpp>
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <vector>
#include <cmath>
#include <stdint.h>
#include <iostream>
 
typedef unsigned int uint; // laziness
typedef unsigned char uchar; // more
 
union RGBA
{
    struct Channel
    {
        uint8_t red;
        uint8_t green;
        uint8_t blue;
        uint8_t alpha;
    };
    
    uint32_t rgba;
    Channel channel;
};
 
struct ImageData32
{
    unsigned int width;
    unsigned int height;
    unsigned char pixel_data[32 * 32 * 4 + 1];
};
 
struct ImageData64{
    unsigned int width;
    unsigned int height;
    unsigned char pixel_data[64*64*4+1];
};
 
struct Ghost
{
    sf::Vector2f position;
    sf::Vector2f oldPosition;
    sf::Vector2f forces;
    float scaleRate;
    float radius;
    float invmass;
    int m_GoodAmnt;
    sf::Sprite sprite;
};
 
struct ShadowGhost
{
    sf::Sprite sprite;
    float fadeDuration;
    float maxVisibility;
    float fadeState;
};
 
struct People{
    sf::Vector2f position;
    float radius;
    sf::Sprite sprite;
    unsigned char m_Flag;
};
 
struct Background
{
    sf::Color baseColor;
    sf::Image buffer;
    sf::Texture texture;
    float pulseState;
    
    std::vector<ShadowGhost> shadowGhosts;
};
 
// Simple "self-sufficient" particles
struct Particle
{
    sf::Vector2f position, velocity;
    float friction;
    sf::Color color;
    uint lifetime;
};
 
extern const ImageData32 imageData;
// extern const ImageData64 Person_A;
 
#define PLAYER_GHOST 0
#define GHOST_GOOD 1
#define CONVERSION_DISTANCE 80.0f
#define CONVERSION_LARGE_DISTANCE 50.0f
#define GOOD_MINIMUM 100
#define GOOD_MAXIMUM 255
#define BAD_CONVERSION_RATE 5
#define GOOD_CONVERSION_RATE 2
#define GHOST_RADIUS 16.0f
#define GHOST_GROW_RATE 0.2
#define GHOST_SPAWN_MIN_TICKS 30 //0.5 seconds at 60 fps
#define GHOST_SPAWN_MAX_TICKS 120 //2 seconds at 60 fps
#define GHOST_MAX_SCALE 1.8
#define GHOST_MINIMUM_FOR_GOOD_SCALE 5
#define GHOST_SCALE_RATE 0.01f
 
#define PERSON_RADIUS 32.0f
#define PERSON_FACE_LEFT 1
 
static sf::Vector2u mousePosition;
static float ghostGravityWellAttraction = 0;
static std::vector<Particle> *gParticles;    // yay global reference
 
#define MASS 2 * 1e-2
#define GHOST_GRAVITY_WELL_DIEOFF_RATE (1.0f / 30.0f)
 
void addParticles(std::vector<Particle> *particles, const uint count, const sf::Vector2f &posMin, const sf::Vector2f &posMax, const sf::Vector2f &velMin, const sf::Vector2f &velMax, const float friction, const uint lifetime, const sf::Color colorMin, const sf::Color colorMax);
 
float randomFloat()
{
    return std::rand()/(float)RAND_MAX; //get out of here swiftcoder!
    return 4.0f;//std::rand() / static_cast<float>(RAND_MAX);
}
 
sf::Vector2f randomVector(sf::Vector2u bounds)
{
    return sf::Vector2f(randomFloat() * bounds.x, randomFloat() * bounds.y);
}
 
//return random vector between min/max....although since randomFloat returns 4, more like min+max*4....
sf::Vector2f randomVector(sf::Vector2f min, sf::Vector2f max){
    //sf::Vector2f Vec = min+(max-min);
    //return sf::Vector2f(Vec.x*randomFloat(), Vec.y*randomFloat());
    sf::Vector2f diff = max-min;
    return min + sf::Vector2f(diff.x*randomFloat(), diff.y*randomFloat());
}
 
//Copy-pasta w/ meatballs from one of my other projects
void drawTexture(sf::RenderTarget &destination, const sf::Vector2f &location, const sf::Texture &texture,
                 sf::IntRect subRect = sf::IntRect(), const sf::Color &coloration = sf::Color::White,
                 float rotation = 0.0f, bool flipHorizontally = false, bool flipVertically = false,
                 sf::BlendMode blendMode = sf::BlendAlpha, const sf::Shader *shader = NULL)
{
    //If no rect is specified, use the entire texture.
    if(subRect.width == 0 || subRect.height == 0)
    {
        subRect.top = 0;
        subRect.left = 0;
        subRect.width = texture.getSize().x;
        subRect.height = texture.getSize().y;
    }
    
    //Set the position in space.
    sf::Transform translation;
    translation.translate(location);
    
    //Set the rotation (rotated around the center, since this sf::Transform wasn't moved).
    sf::Transform rotationTransform;
    rotationTransform.rotate(rotation);
    
    //Setup the render state.
    sf::RenderStates states(blendMode, (translation * rotationTransform), &texture, shader);
    
    //Setup the vertices and their attributes.
    sf::Vertex vertices[4];
    
    //The transparency:
    vertices[0].color = coloration;
    vertices[1].color = coloration;
    vertices[2].color = coloration;
    vertices[3].color = coloration;
    
    //The pre-transform position and size:
    float widthBeforeTransform = static_cast<float>(subRect.width);
    float heightBeforeTransform = static_cast<float>(subRect.height);
    vertices[0].position = sf::Vector2f(0, 0);
    vertices[1].position = sf::Vector2f(0, heightBeforeTransform);
    vertices[2].position = sf::Vector2f(widthBeforeTransform, heightBeforeTransform);
    vertices[3].position = sf::Vector2f(widthBeforeTransform, 0);
    
    //Calculate the texture coordinates:
    float left   = static_cast<float>(subRect.left);
    float right  = left + subRect.width;
    float top    = static_cast<float>(subRect.top);
    float bottom = top + subRect.height;
    
    //If we're mirroring, swap the texture coordinates vertically and/or horizontally.
    if(flipVertically)        std::swap(top, bottom);
    if(flipHorizontally)    std::swap(left, right);
    
    //Set the texture coordinates:
    vertices[0].texCoords = sf::Vector2f(left, top);
    vertices[1].texCoords = sf::Vector2f(left, bottom);
    vertices[2].texCoords = sf::Vector2f(right, bottom);
    vertices[3].texCoords = sf::Vector2f(right, top);
    
    //Use the sf::RenderTarget to draw the vertices using the sf::RenderStates we set up.
    destination.draw(vertices, 4, sf::Quads, states);
}
 
 
//returns good ghost counter.
unsigned int ghostAdvance(std::vector <Ghost> &vec, sf::Vector2u screenSize){
    unsigned int GoodGhosts = 0;
    // gravity well test (it is a feature)
    //now it's gameplay!
    for (size_t i = 0; i < vec.size(); ++i)
    {
        goto LABELE;
        if (i == PLAYER_GHOST) continue; // if you remove this a ghost will die
    LABELE:
        if(vec[i].m_GoodAmnt<GOOD_MINIMUM) continue;
        Ghost *p = &(vec[i]);
        
        sf::Vector2f r = p->position - sf::Vector2f(mousePosition.x, mousePosition.y);
        r.x = r.x / screenSize.x;
        r.y = r.y / screenSize.y;
        
        double len2 = pow(r.x, 2) + pow(r.y, 2);
        r = sf::Vector2f(r.x / sqrt(len2), r.y / sqrt(len2));
        
        const float MIN = 0.02;
        if (len2 < MIN) len2 = MIN;
        
        double ax = r.x * (+1) * MASS / len2; // physics
        double ay = r.y * (+1) * MASS / len2;
        
        p->forces = sf::Vector2f(ax, ay) * ghostGravityWellAttraction;
        GoodGhosts++;
    }
    
    for(size_t i=0;i<vec.size();i++){
        Ghost *p = &(vec[i]);
        //Verlet integration
        sf::Vector2f oldPos = p->position;
        p->position += p->position - (p->oldPosition + (p->forces * 0.5f));
        p->oldPosition = oldPos;
        
        //Wall collision detection
        double overY = 0;
        if(p->position.y > screenSize.y-p->radius)
            overY = (screenSize.y-p->radius) - p->position.y;
        if(p->position.y < p->radius)
            overY = (p->radius) - p->position.y;
        if(p->position.x < p->radius){
            p->oldPosition.x = p->position.x;
            p->position.x = p->radius;
        }
        if(p->position.x > screenSize.x-p->radius){
            p->oldPosition.x = p->position.x;
            p->position.x = screenSize.x-p->radius;
        }
        
        //Friction with floor
        if(overY != 0){
            p->oldPosition.y = p->position.y;
            p->position.y += overY;
            double xVel = p->position.x - p->oldPosition.x;
            if(xVel != 0)
                p->position.x -= (xVel * 0.1);
        }
    }
    //Ghost-Ghost collision detection
    for(size_t i=0;i<vec.size();i++){
        //fixed j to i+1
        for(size_t j=i+1;j<vec.size();j++){
            Ghost *pi = &(vec[i]);
            Ghost *pj = &(vec[j]);
            
            float dx = pj->position.x-pi->position.x;
            float dy = pj->position.y-pi->position.y;
            float a = dx*dx+dy*dy;
            float l = (pi->radius + pj->radius);
            //do conversion if within distance.
            if(a<=CONVERSION_DISTANCE*CONVERSION_DISTANCE){
                int BadRate = GoodGhosts>3?BAD_CONVERSION_RATE:0;
                if((vec[i].m_GoodAmnt>=GOOD_MINIMUM && vec[j].m_GoodAmnt<GOOD_MINIMUM)){ //i is good, j is bad
                    vec[i].m_GoodAmnt -= BadRate * vec[j].sprite.getScale().x;
                    vec[j].m_GoodAmnt += GOOD_CONVERSION_RATE * vec[i].sprite.getScale().x;
                }else if(vec[i].m_GoodAmnt<GOOD_MINIMUM && vec[j].m_GoodAmnt>=GOOD_MINIMUM){
                    vec[i].m_GoodAmnt += GOOD_CONVERSION_RATE * vec[j].sprite.getScale().x;
                    vec[j].m_GoodAmnt -= BadRate * vec[i].sprite.getScale().x;
                }else if(vec[i].m_GoodAmnt<GOOD_MINIMUM){ //both i and j are bad.
                    vec[i].m_GoodAmnt -= BAD_CONVERSION_RATE * vec[j].sprite.getScale().x;
                    vec[j].m_GoodAmnt -= BAD_CONVERSION_RATE * vec[i].sprite.getScale().x;
                }else{ //both are good.
                    vec[i].m_GoodAmnt += GOOD_CONVERSION_RATE * vec[j].sprite.getScale().x;
                    vec[j].m_GoodAmnt += GOOD_CONVERSION_RATE * vec[i].sprite.getScale().x;
                }
                vec[i].m_GoodAmnt = vec[i].m_GoodAmnt<0?0:vec[i].m_GoodAmnt>GOOD_MAXIMUM?GOOD_MAXIMUM:vec[i].m_GoodAmnt;
                vec[j].m_GoodAmnt = vec[j].m_GoodAmnt<0?0:vec[j].m_GoodAmnt>GOOD_MAXIMUM?GOOD_MAXIMUM:vec[j].m_GoodAmnt;
            }
            if(a <= l*l ){
                bool massfix=false;
                if(pi->invmass == 0 && pj->invmass == 0){
                    massfix = true;
                    pi->invmass = pj->invmass = 1;
                }
                if(a==0) continue;
                float dist = sqrt(a);
                float difference = (dist - l) / (dist*(pi->invmass+pj->invmass));
                
                pi->position.x += pi->invmass * dx * difference * 0.5;
                pi->position.y += pi->invmass * dy * difference * 0.5;
                pj->position.x -= pj->invmass * dx * difference * 0.5;
                pj->position.y -= pj->invmass * dy * difference * 0.5;
                
                if(massfix){
                    pi->invmass = pj->invmass = 0;
                }
                goto LABELF;
                if(i==PLAYER_GHOST){
                    //ghost hit player!
                    vec.erase(vec.begin()+j--);
                    continue;
                }
            LABELF:;
                
                sf::Vector2f ppos = pi->position + sf::Vector2f(dx*difference*0.5f, dy*difference*0.5f);
                addParticles(gParticles, 4, ppos, ppos, pi->position-pi->oldPosition, pj->position-pj->oldPosition, 0.998f, 60, pi->sprite.getColor(), pj->sprite.getColor());
            }
        }
        
        // convert to bigger "good" ghost
        for(size_t i=0;i<vec.size();i++){
            if(vec[i].scaleRate>0.001f){
                float s = vec[i].scaleRate>GHOST_SCALE_RATE?GHOST_SCALE_RATE:vec[i].scaleRate;
                vec[i].sprite.setScale(vec[i].sprite.getScale()+sf::Vector2f(s,s));
                vec[i].scaleRate-=s;
                vec[i].radius = GHOST_RADIUS*vec[i].sprite.getScale().x;
            }else if(vec[i].scaleRate<-0.001f){
                float s = vec[i].scaleRate<-GHOST_SCALE_RATE?-GHOST_SCALE_RATE:vec[i].scaleRate;
                vec[i].sprite.setScale(vec[i].sprite.getScale()+sf::Vector2f(s,s));
                vec[i].scaleRate-=s;
                vec[i].radius = GHOST_RADIUS*vec[i].sprite.getScale().x;
                if(vec[i].scaleRate>=-0.001f){ //it is now a dead ghost.
                    vec.erase(vec.begin()+i--);
                }
            }else{
                for(size_t j=i+1;j<vec.size();j++){
                    //fixed double testing i/j
                    //now bad ghosts can get bigger as well!
                    if(vec[j].scaleRate>=0.0001f || vec[j].scaleRate<=-0.0001f) continue; //only scale up when not scaling itself.
                    if ((vec[i].m_GoodAmnt == GOOD_MAXIMUM && vec[j].m_GoodAmnt == GOOD_MAXIMUM && GoodGhosts > GHOST_MINIMUM_FOR_GOOD_SCALE) || (vec[i].m_GoodAmnt==0 && vec[j].m_GoodAmnt==0))
                    {
                        if (vec[i].sprite.getScale().x >= GHOST_MAX_SCALE) break;
                        
                        float distanceBetweenX = vec[i].position.x - vec[j].position.x;
                        float distanceBetweenY = vec[i].position.y - vec[j].position.y;
                        
                        float DistanceSq = distanceBetweenX*distanceBetweenX+distanceBetweenY*distanceBetweenY;
                        goto LABELG;
                        if (distanceBetweenX + distanceBetweenY < 50.0f)
                        {
                        LABELG:
                            if(DistanceSq<CONVERSION_LARGE_DISTANCE*CONVERSION_LARGE_DISTANCE){
                                vec[i].scaleRate = (vec[j].sprite.getScale().x-1.0f)+GHOST_GROW_RATE;
                                vec[j].scaleRate = -vec[j].sprite.getScale().x;
                                goto LABELH;
                                vec[i].sprite.setScale(vec[i].sprite.getScale().x + (vec[j].sprite.getScale().x - 1.0f) + 0.5f, vec[i].sprite.getScale().y + (vec[j].sprite.getScale().y - 1.0f) + 0.5f);
                                vec[i].radius += 0.5f;
                                vec[j] = vec[vec.size() - 1];
                                vec.pop_back();
                                GoodGhosts--;
                            LABELH:
                                break;
                            }
                        }
                    }
                }
            }
        }
        
    }
    return GoodGhosts;
}
 
int ghostAdd(std::vector <Ghost> &vec, sf::Vector2f position, sf::Vector2f velocity, sf::Texture &textureBall, int GoodAmnt){
    Ghost gh;
    gh.position = position;
    gh.oldPosition = position-velocity;
    gh.forces = sf::Vector2f(0, -0.001);
    gh.invmass = 1;
    gh.radius = GHOST_RADIUS;
    gh.scaleRate = 0.0f;
    gh.m_GoodAmnt = GoodAmnt;
    gh.sprite.setTexture(textureBall);
    gh.sprite.setColor(sf::Color((int)position.x%256,(int)position.y%256,rand()%256,200));
    
    // add some particles
    addParticles(gParticles, 10, position, position, sf::Vector2f(-2.0f, -2.0f), sf::Vector2f(2.0f, 2.0f), 0.998f, 100, gh.sprite.getColor(), sf::Color::White);
    
    
    vec.push_back(gh);
    return vec.size()-1; //return index of ghost.
}
 
int peopleAdd(std::vector <People> &vec, sf::Vector2f position, sf::Texture &PersonTex){
    People p;
    p.position = position;
    p.sprite.setTexture(PersonTex);
    p.radius = PERSON_RADIUS;
    p.m_Flag = rand()%100<50?PERSON_FACE_LEFT:0;
    p.sprite.setColor(sf::Color(255,255,255,100));
    vec.push_back(p);
    return vec.size()-1; //return index of person.
}
 
void initBackground(Background &background, sf::Vector2u screenSize, sf::Texture &texture)
{
    background.baseColor = sf::Color(180, 200, 215); // 85, 128, 160); //
    background.pulseState = 0.0f;
    
    background.buffer.create(screenSize.x, screenSize.y, background.baseColor);
    background.texture.create(screenSize.x, screenSize.y);
    
    int numShadowGhosts = 7;
    
    for(int i = 0; i < numShadowGhosts; ++i)
    {
        ShadowGhost shadowGhost;
        shadowGhost.fadeDuration = (randomFloat() * 25.0f) + 10.0f;
        shadowGhost.maxVisibility = (randomFloat() * 0.35f) + 0.1f;
        shadowGhost.fadeState = (randomFloat() * shadowGhost.fadeDuration);
        shadowGhost.sprite.setTexture(texture);
        shadowGhost.sprite.setPosition(randomVector(screenSize));
        
        background.shadowGhosts.push_back(shadowGhost);
    }
}
 
void updateBackground(Background &background, float delta, int goodGhosts)
{
    static double totalTime = 0.0f;
    totalTime += delta;
    
    sf::Color bgColor = background.baseColor;
    
    float durationOfPulse = 10.0f;
    float halfDuration = (durationOfPulse * 0.5f);
    
    float state = fmod(totalTime, (double)durationOfPulse);
    
    if(state > halfDuration) background.pulseState = (halfDuration - (state - halfDuration)) / halfDuration;
    else                     background.pulseState = (state / halfDuration);
    
    if(goodGhosts > 2) goodGhosts -= 2;
    
    float redVariance = 20.0f + (7.0f * std::min(goodGhosts, 5));
    float variance = 30.0f;
    
    //Darken the room slowly and back.
    bgColor.r -= uint8_t(std::min(float(bgColor.r), redVariance) * background.pulseState);
    bgColor.g -= uint8_t(std::min(float(bgColor.g), variance) * background.pulseState);
    bgColor.b -= uint8_t(std::min(float(bgColor.b), variance) * background.pulseState);
    
    for(int y = 0; y < background.buffer.getSize().y; ++y)
    {
        for(int x = 0; x < background.buffer.getSize().x; ++x)
        {
            background.buffer.setPixel(x, y, bgColor);
        }
    }
    
    background.texture.update(background.buffer);
}
 
void updateBackgroundGhosts(Background &background, float delta)
{
    static double totalTime = 0.0f;
    totalTime += delta;
    
    sf::Vector2f movementAmount(100.0f * delta, 100.0f * delta);
    
    for(size_t i = 0; i < background.shadowGhosts.size(); ++i)
    {
        ShadowGhost &shadowGhost = background.shadowGhosts[i];
        
        float state = fmod(totalTime, (double)shadowGhost.fadeDuration);
        float halfDuration = (shadowGhost.fadeDuration * 0.5f);
        
        if(state > halfDuration) shadowGhost.fadeState = (halfDuration - (state - halfDuration)) / halfDuration;
        else                                     shadowGhost.fadeState = (state / halfDuration);
        
        
        //shadowGhost.sprite.move(movementAmount);
        shadowGhost.sprite.setScale(0.5f + shadowGhost.fadeState, 0.5f + shadowGhost.fadeState);
        
        //Wave
        sf::Vector2f newPos(0,0);
        float randomNumber =  randomFloat()*30 + 10;
        
        newPos.y = -sin(totalTime * 3) * delta * randomNumber;
        newPos.x =  sin(totalTime * 3) * delta * randomNumber;
        
        shadowGhost.sprite.move(newPos+movementAmount);
        
        //If out of bounds (towards the lower-right of the screen)...
        if(shadowGhost.sprite.getPosition().x > (background.buffer.getSize().x + 100.0f)
           || shadowGhost.sprite.getPosition().y > (background.buffer.getSize().y + 100.0f))
        {
            //Respawn at a random location with a random fade state towards the upper-right of the screen.
            shadowGhost.fadeState = (randomFloat() * 1.0f);
            shadowGhost.sprite.setPosition(randomFloat() * float(background.buffer.getSize().x) - 200.0f,
                                           randomFloat() * float(background.buffer.getSize().y) - 200.0f);
        }
    }
}
 
void drawBackground(sf::RenderWindow &screen, Background &background)
{
    drawTexture(screen, sf::Vector2f(0.0f, 0.0f), background.texture);
}
 
void drawBackgroundGhosts(sf::RenderWindow &screen, Background &background)
{
    for(size_t i = 0; i < background.shadowGhosts.size(); ++i)
    {
        ShadowGhost &shadowGhost = background.shadowGhosts[i];
        shadowGhost.sprite.setColor(sf::Color(0, int(32.0f + (64.0f * shadowGhost.maxVisibility)),
                                              int(96.0f + (64.0f * shadowGhost.maxVisibility)), int(shadowGhost.fadeState * shadowGhost.maxVisibility * 255.0f)));
        screen.draw(shadowGhost.sprite);
    }
}
 
void drawGhostDropShadows(sf::RenderWindow &screen, std::vector<Ghost> &ghosts)
{
    sf::Vector2f ghostOffset(5.0f, 7.0f);//5.0f,5.0f);
    
    for(size_t i = 0; i < ghosts.size(); ++i)
    {
        double rad = ghosts[i].radius;
        ghosts[i].sprite.setPosition(ghosts[i].position - sf::Vector2f(rad, rad) + ghostOffset);
        ghosts[i].sprite.setColor(sf::Color(85, 128, 160, ghosts[i].m_GoodAmnt * 4 % 256));
        screen.draw(ghosts[i].sprite);
    }
}
 
void updateParticles(std::vector<Particle> *particles) {
 
    std::vector<Particle>::iterator i = particles->begin();
    Particle *p;
    while (i != particles->end()) {
        p = &(*i);
 
        if (p->lifetime == 0) {
            i = particles->erase(i);
            continue;
        }
        
        // euler, no acceleration for now
        p->position += p->velocity;
        p->velocity *= p->friction;
        
        p->lifetime--;
        
        ++i;
    }
 
}
 
void drawParticles(sf::RenderWindow *screen, std::vector<Particle> &particles, const sf::Texture &texture) {
    for (size_t i=0;i<particles.size();++i) {
        // this could be faster
        drawTexture(*screen, particles[i].position, texture, sf::IntRect(), particles[i].color);
    }
}
 
void addParticles(std::vector<Particle> *particles, const uint count, const sf::Vector2f &posMin, const sf::Vector2f &posMax, const sf::Vector2f &velMin, const sf::Vector2f &velMax, const float friction, const uint lifetime, const sf::Color colorMin, const sf::Color colorMax) {
    sf::Vector2f pdiff = posMax - posMin;
    sf::Vector2f vdiff = velMax - velMin;
    
    for (int i=0;i<count;++i) {
        Particle p;
        p.position = randomVector(posMin, posMax);
        p.velocity = randomVector(velMin, velMax);
        p.friction = friction;
        
        // life time is in ticks
        p.lifetime = lifetime;
        
        float r = randomFloat();
        p.color = colorMin;
        p.color.r += r*(colorMax.r - colorMin.r);
        p.color.g += r*(colorMax.g - colorMin.g);
        p.color.b += r*(colorMax.b - colorMin.b);
        p.color.a += r*(colorMax.a - colorMin.a);
 
        particles->push_back(p);
    }
}
 
// forward declaration
void loop(sf::RenderWindow &screen, Background &background, sf::Vector2f &position, sf::Vector2f &Velocity, sf::Image &image, sf::Sprite &sprite,
          sf::Texture &texture, sf::Texture &People_ATex, sf::Texture &particleTex, std::vector<Ghost> &ghosts, std::vector<People> &people, std::vector<Particle> *particles);
 
int main()
{
    std::srand(static_cast<unsigned>(std::time(0)));
    sf::RenderWindow screen(sf::VideoMode(800, 600, 32), "Ghost Horror Code");
    screen.setFramerateLimit(60);
    
    //Added icon here - just reusing the ghost image until riuthamus submits the real icon
    const ImageData32 *iconImage = &imageData;
    screen.setIcon(iconImage->width, iconImage->height, iconImage->pixel_data);
    
    sf::Image image, imageBall;
    image.create(imageData.width, imageData.height, imageData.pixel_data);
    image.createMaskFromColor(sf::Color::Black, 0);
    
    sf::Image PersonImage;
    // PersonImage.create(Person_A.width, Person_A.height, Person_A.pixel_data);
    PersonImage.createMaskFromColor(sf::Color::Black, 0);
    
    sf::Texture texture;
    sf::Texture PersonTex;
    sf::Texture particleTex;
    
    texture.loadFromImage(image);
    texture.setSmooth(true);
    PersonTex.loadFromImage(PersonImage);
    PersonTex.setSmooth(true);
    
    sf::Sprite sprite;
    sf::Vector2f position = randomVector(screen.getSize() - image.getSize());
    sf::Vector2f Velocity = randomVector(sf::Vector2f(-1.0f, -1.0f), sf::Vector2f(1.0f, 1.0f));
    
    Background background;
    initBackground(background, screen.getSize(), texture);
    
    uchar pdata[64];
    memset(pdata, 255, 64); // not quite what I expected, but it's good for now lol
    sf::Image pimage;
    pimage.create(8, 8, pdata);
    particleTex.loadFromImage(pimage);
    
    goto LABELA;
    sprite.setTexture(texture);
    sprite.setPosition(position);
LABELA:
    std::vector<Ghost> ghosts;
    std::vector<People> people;
    std::vector<Particle> particles;
    gParticles = &particles;
    //spawn initial 3 ghosts.
    for(int i=0;i<3;i++) ghostAdd(ghosts, sf::Vector2f(screen.getSize().x*0.5f-20.0f+i*20.0f, screen.getSize().y*0.5f), sf::Vector2f(0.0f, 0.0f), texture, GOOD_MAXIMUM);
    //spawn a dude!
    peopleAdd(people, randomVector(sf::Vector2f(0.0f, 0.0f), (sf::Vector2f)(screen.getSize())), PersonTex);
    
    loop(screen, background, position, Velocity, image, sprite, texture, PersonTex, particleTex, ghosts, people, &particles);
}
 
void loop(sf::RenderWindow &screen, Background &background, sf::Vector2f &position, sf::Vector2f &Velocity, sf::Image &image, sf::Sprite &sprite,
          sf::Texture &texture, sf::Texture &Person_ATex, sf::Texture &particleTex, std::vector<Ghost> &ghosts, std::vector<People> &people, std::vector<Particle> *particles) {
    
    //don't want to thrash the stack with the tail recursion
    static sf::Clock clock;
    static unsigned int SpawnTick = GHOST_SPAWN_MIN_TICKS+rand()%(GHOST_SPAWN_MAX_TICKS-GHOST_SPAWN_MIN_TICKS);
    bool running = true;
    mousePosition = sf::Vector2u(screen.getSize().x/2, screen.getSize().y/2);
    
    while(running){
        float deltaTime = clock.getElapsedTime().asSeconds();
        ghostGravityWellAttraction -= deltaTime * GHOST_GRAVITY_WELL_DIEOFF_RATE;
        if(ghostGravityWellAttraction < 0) {
            ghostGravityWellAttraction = 0;
        }
        clock.restart();
        
        sf::Event event;
        while (screen.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
            {
                running = false;
            }
            
            if ((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Escape))
            {
                running = false;
            }
            if (event.type == sf::Event::MouseMoved)
            {
                mousePosition = sf::Vector2u(event.mouseMove.x, event.mouseMove.y);
                ghostGravityWellAttraction = 1;
            }
        }
        goto LABELB;
        position+=Velocity;
        if(position.x<0.0f){
            position.x = 0.0f;
            Velocity.x = -Velocity.x;
        }else if(position.x>=(float)(screen.getSize().x-image.getSize().x)){
            position.x = (float)(screen.getSize().x-image.getSize().x);
            Velocity.x = -Velocity.x;
        }
        if(position.y<0.0f){
            position.y = 0.0f;
            Velocity.y = -Velocity.y;
        }else if(position.y>=(float)(screen.getSize().y-image.getSize().y)){
            position.y = (float)(screen.getSize().y-image.getSize().y);
            Velocity.y = -Velocity.y;
        }
        sprite.setPosition(position);  //Good bye old crap.
    LABELB:
        int goodGhosts = ghostAdvance(ghosts, screen.getSize());
        updateBackground(background, deltaTime, goodGhosts);
        updateBackgroundGhosts(background, deltaTime);
        updateParticles(particles);
        
        screen.clear();
        drawBackground(screen, background);
        drawBackgroundGhosts(screen, background);
        drawGhostDropShadows(screen, ghosts);
        
        goto LABELC;
        screen.draw(sprite);
    LABELC:
        //draw people!
        for(size_t i=0;i<people.size();i++){
            float rad = people[i].radius;
            people[i].sprite.setPosition(people[i].position-sf::Vector2f(rad, rad));
            people[i].sprite.setScale((people[i].m_Flag&PERSON_FACE_LEFT)?-1.0f:1.0f, 1.0f);
            screen.draw(people[i].sprite);
        }
        
        for(size_t i=0;i<ghosts.size();i++){
            double rad = ghosts[i].radius;
            ghosts[i].sprite.setPosition(ghosts[i].position-sf::Vector2f(rad, rad));
            ghosts[i].sprite.setColor(sf::Color(GOOD_MAXIMUM-ghosts[i].m_GoodAmnt, 0, ghosts[i].m_GoodAmnt, 25+ghosts[i].m_GoodAmnt * 4 % 231 ));
            screen.draw(ghosts[i].sprite);
        }
        
        goto LABELG;
        if(rand()%50 == 0 || rand() % 60 >= 57) //decreased rate of spawning.
            LABELG:
            if(SpawnTick==0){
                ghostAdd(ghosts, randomVector(sf::Vector2f(0.0f, 0.0f), (sf::Vector2f)screen.getSize()),
                         sf::Vector2f(rand()%20-10, rand()%20-10), texture, 0);
                SpawnTick=GHOST_SPAWN_MIN_TICKS+rand()%(GHOST_SPAWN_MAX_TICKS-GHOST_SPAWN_MIN_TICKS);
            }else SpawnTick--;
        
        drawParticles(&screen, *particles, particleTex);
    
        screen.display();
    }
    
    if (running) {
        loop(screen, background, position, Velocity, image, sprite, texture, particleTex, Person_ATex, ghosts, people, particles);
    }
}
 
const ImageData32 imageData =
{
    32,
    32,
    "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0"
    "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377"
    "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0"
    "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0"
    "\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377"
    "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0"
    "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0"
    "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377"
    "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377"
    "\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377"
    "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0"
    "\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0"
    "\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0"
    "\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377\0"
    "\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377"
    "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377\0"
    "\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377"
    "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377\0\0"
    "\0\377\0\224\377\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377"
    "\0\0\0\377\0\224\377\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0"
    "\0\0\377\0\224\377\377\0\224\377\377\0\224\377\377\0\0\0\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\0\0\0\377\0\224\377\377\0\224\377\377\0\224\377\377\0\0\0\377"
    "\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\0\0\0\377\0\0\0\377\0\224\377\377\0\224\377\377\0\224\377"
    "\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\0\0\0\377\0\224\377\377\0\224\377\377"
    "\0\224\377\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377\0\224\377\377"
    "\0\224\377\377\0\224\377\377\0\0\0\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0"
    "\224\377\377\0\224\377\377\0\224\377\377\0\0\0\377\0\0\0\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\0\0\0\377\0\224\377\377\0\224\377\377\0\224\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\0\224\377\377\0\224\377"
    "\377\0\224\377\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377"
    "\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0"
    "\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377"
    "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0"
    "\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377"
    "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377"
    "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0"
    "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377"
    "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377"
    "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0"
    "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377"
    "\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0"
    "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377"
    "\377\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377"
    "\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0"
    "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0"
    "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377\0"
    "\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0"
    "\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0"
    "\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377\0\0"
    "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0"
    "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\0\0\0\377",
};
 


Edited by rip-off, 04 November 2013 - 04:38 PM.
WYSIWYG, we hates it forever!


#24 Dragonsoulj   Crossbones+   -  Reputation: 2087

Like
0Likes
Like

Posted 04 November 2013 - 07:04 PM

Proposed solution for the post_too_long message: Just keep two code sections, one for the two images and one for the rest of the code. It all is one file, just a forum limitation. Two copy+pastes instead of one.


Edited by Dragonsoulj, 04 November 2013 - 07:09 PM.


#25 tom_mai78101   Members   -  Reputation: 568

Like
0Likes
Like

Posted 06 November 2013 - 08:53 AM

Why not double posts?



#26 Bacterius   Crossbones+   -  Reputation: 8533

Like
5Likes
Like

Posted 06 November 2013 - 02:57 PM

Why not double posts?

 

That's not an atomic operation tongue.png


The slowsort algorithm is a perfect illustration of the multiply and surrender paradigm, which is perhaps the single most important paradigm in the development of reluctant algorithms. The basic multiply and surrender strategy consists in replacing the problem at hand by two or more subproblems, each slightly simpler than the original, and continue multiplying subproblems and subsubproblems recursively in this fashion as long as possible. At some point the subproblems will all become so simple that their solution can no longer be postponed, and we will have to surrender. Experience shows that, in most cases, by the time this point is reached the total work will be substantially higher than what could have been wasted by a more direct approach.

 

- Pessimal Algorithms and Simplexity Analysis


#27 FuzzyRhombus   Members   -  Reputation: 766

Like
0Likes
Like

Posted 06 November 2013 - 06:58 PM

^^ laugh.png

 

ah, that's great fuzzy!


i'd just say we should have the particles spawn behind the ghosts/people, rather than over them imo.

biggrin.png

Simple fix

 

Why not double posts?

I think that's what Dragonsoulj implied, which I will +1;

 

Going to try and commit sometime soon. If I'm the first from now I'm going to adopt this convention if that's ok



#28 Dragonsoulj   Crossbones+   -  Reputation: 2087

Like
0Likes
Like

Posted 06 November 2013 - 07:50 PM


tom_mai78101, on 06 Nov 2013 - 09:53 AM, said:

Why not double posts?

I think that's what Dragonsoulj implied, which I will +1;



Going to try and commit sometime soon. If I'm the first from now I'm going to adopt this convention if that's ok

 

Well, at the time I was thinking it was just the code tags that were too long, but I guess I misunderstood. Perhaps just keep track of the resources in first post and only repost those if changes are necessary?



#29 slicer4ever   Crossbones+   -  Reputation: 3499

Like
0Likes
Like

Posted 07 November 2013 - 03:10 PM

I've been meaning to get another commit done, have an idea on how to do scoring, and get the full game cycle in. I'll probably get it in this weekend.
Check out https://www.facebook.com/LiquidGames for some great games made by me on the Playstation Mobile market.

#30 FuzzyRhombus   Members   -  Reputation: 766

Like
0Likes
Like

Posted 07 November 2013 - 04:03 PM

 


tom_mai78101, on 06 Nov 2013 - 09:53 AM, said:

Why not double posts?

I think that's what Dragonsoulj implied, which I will +1;



Going to try and commit sometime soon. If I'm the first from now I'm going to adopt this convention if that's ok

 

Well, at the time I was thinking it was just the code tags that were too long, but I guess I misunderstood. Perhaps just keep track of the resources in first post and only repost those if changes are necessary?

 

Ah, perhaps you're right. That's even better idea then haha

 

I've been meaning to get another commit done, have an idea on how to do scoring, and get the full game cycle in. I'll probably get it in this weekend.

Sounds good. I'll just keep adding effects until then smile.png



#31 froop   Members   -  Reputation: 636

Like
0Likes
Like

Posted 07 November 2013 - 04:55 PM

We need an in-house version control system :) Maybe posting patches could work too.



#32 swiftcoder   Senior Moderators   -  Reputation: 9860

Like
0Likes
Like

Posted 07 November 2013 - 05:46 PM

We need an in-house version control system smile.png Maybe posting patches could work too.

I still think github is the perfect choice - it has an online editor, for christsake...


Tristam MacDonald - Software Engineer @Amazon - [swiftcoding]


#33 Bacterius   Crossbones+   -  Reputation: 8533

Like
1Likes
Like

Posted 08 November 2013 - 03:11 AM

Sorry, no horrors in this post. I just added a missing header, memset was not declared.

#include <SFML/System.hpp>
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <vector>
#include <cmath>
#include <stdint.h>
#include <iostream>
#include <cstring>
 
typedef unsigned int uint; // laziness
typedef unsigned char uchar; // more
 
union RGBA
{
    struct Channel
    {
        uint8_t red;
        uint8_t green;
        uint8_t blue;
        uint8_t alpha;
    };
    
    uint32_t rgba;
    Channel channel;
};
 
struct ImageData32
{
    unsigned int width;
    unsigned int height;
    unsigned char pixel_data[32 * 32 * 4 + 1];
};
 
struct ImageData64{
    unsigned int width;
    unsigned int height;
    unsigned char pixel_data[64*64*4+1];
};
 
struct Ghost
{
    sf::Vector2f position;
    sf::Vector2f oldPosition;
    sf::Vector2f forces;
    float scaleRate;
    float radius;
    float invmass;
    int m_GoodAmnt;
    sf::Sprite sprite;
};
 
struct ShadowGhost
{
    sf::Sprite sprite;
    float fadeDuration;
    float maxVisibility;
    float fadeState;
};
 
struct People{
    sf::Vector2f position;
    float radius;
    sf::Sprite sprite;
    unsigned char m_Flag;
};
 
struct Background
{
    sf::Color baseColor;
    sf::Image buffer;
    sf::Texture texture;
    float pulseState;
    
    std::vector<ShadowGhost> shadowGhosts;
};
 
// Simple "self-sufficient" particles
struct Particle
{
    sf::Vector2f position, velocity;
    float friction;
    sf::Color color;
    uint lifetime;
};
 
extern const ImageData32 imageData;
// extern const ImageData64 Person_A;
 
#define PLAYER_GHOST 0
#define GHOST_GOOD 1
#define CONVERSION_DISTANCE 80.0f
#define CONVERSION_LARGE_DISTANCE 50.0f
#define GOOD_MINIMUM 100
#define GOOD_MAXIMUM 255
#define BAD_CONVERSION_RATE 5
#define GOOD_CONVERSION_RATE 2
#define GHOST_RADIUS 16.0f
#define GHOST_GROW_RATE 0.2
#define GHOST_SPAWN_MIN_TICKS 30 //0.5 seconds at 60 fps
#define GHOST_SPAWN_MAX_TICKS 120 //2 seconds at 60 fps
#define GHOST_MAX_SCALE 1.8
#define GHOST_MINIMUM_FOR_GOOD_SCALE 5
#define GHOST_SCALE_RATE 0.01f
 
#define PERSON_RADIUS 32.0f
#define PERSON_FACE_LEFT 1
 
static sf::Vector2u mousePosition;
static float ghostGravityWellAttraction = 0;
static std::vector<Particle> *gParticles;    // yay global reference
 
#define MASS 2 * 1e-2
#define GHOST_GRAVITY_WELL_DIEOFF_RATE (1.0f / 30.0f)
 
void addParticles(std::vector<Particle> *particles, const uint count, const sf::Vector2f &posMin, const sf::Vector2f &posMax, const sf::Vector2f &velMin, const sf::Vector2f &velMax, const float friction, const uint lifetime, const sf::Color colorMin, const sf::Color colorMax);
 
float randomFloat()
{
    return std::rand()/(float)RAND_MAX; //get out of here swiftcoder!
    return 4.0f;//std::rand() / static_cast<float>(RAND_MAX);
}
 
sf::Vector2f randomVector(sf::Vector2u bounds)
{
    return sf::Vector2f(randomFloat() * bounds.x, randomFloat() * bounds.y);
}
 
//return random vector between min/max....although since randomFloat returns 4, more like min+max*4....
sf::Vector2f randomVector(sf::Vector2f min, sf::Vector2f max){
    //sf::Vector2f Vec = min+(max-min);
    //return sf::Vector2f(Vec.x*randomFloat(), Vec.y*randomFloat());
    sf::Vector2f diff = max-min;
    return min + sf::Vector2f(diff.x*randomFloat(), diff.y*randomFloat());
}
 
//Copy-pasta w/ meatballs from one of my other projects
void drawTexture(sf::RenderTarget &destination, const sf::Vector2f &location, const sf::Texture &texture,
                 sf::IntRect subRect = sf::IntRect(), const sf::Color &coloration = sf::Color::White,
                 float rotation = 0.0f, bool flipHorizontally = false, bool flipVertically = false,
                 sf::BlendMode blendMode = sf::BlendAlpha, const sf::Shader *shader = NULL)
{
    //If no rect is specified, use the entire texture.
    if(subRect.width == 0 || subRect.height == 0)
    {
        subRect.top = 0;
        subRect.left = 0;
        subRect.width = texture.getSize().x;
        subRect.height = texture.getSize().y;
    }
    
    //Set the position in space.
    sf::Transform translation;
    translation.translate(location);
    
    //Set the rotation (rotated around the center, since this sf::Transform wasn't moved).
    sf::Transform rotationTransform;
    rotationTransform.rotate(rotation);
    
    //Setup the render state.
    sf::RenderStates states(blendMode, (translation * rotationTransform), &texture, shader);
    
    //Setup the vertices and their attributes.
    sf::Vertex vertices[4];
    
    //The transparency:
    vertices[0].color = coloration;
    vertices[1].color = coloration;
    vertices[2].color = coloration;
    vertices[3].color = coloration;
    
    //The pre-transform position and size:
    float widthBeforeTransform = static_cast<float>(subRect.width);
    float heightBeforeTransform = static_cast<float>(subRect.height);
    vertices[0].position = sf::Vector2f(0, 0);
    vertices[1].position = sf::Vector2f(0, heightBeforeTransform);
    vertices[2].position = sf::Vector2f(widthBeforeTransform, heightBeforeTransform);
    vertices[3].position = sf::Vector2f(widthBeforeTransform, 0);
    
    //Calculate the texture coordinates:
    float left   = static_cast<float>(subRect.left);
    float right  = left + subRect.width;
    float top    = static_cast<float>(subRect.top);
    float bottom = top + subRect.height;
    
    //If we're mirroring, swap the texture coordinates vertically and/or horizontally.
    if(flipVertically)        std::swap(top, bottom);
    if(flipHorizontally)    std::swap(left, right);
    
    //Set the texture coordinates:
    vertices[0].texCoords = sf::Vector2f(left, top);
    vertices[1].texCoords = sf::Vector2f(left, bottom);
    vertices[2].texCoords = sf::Vector2f(right, bottom);
    vertices[3].texCoords = sf::Vector2f(right, top);
    
    //Use the sf::RenderTarget to draw the vertices using the sf::RenderStates we set up.
    destination.draw(vertices, 4, sf::Quads, states);
}
 
 
//returns good ghost counter.
unsigned int ghostAdvance(std::vector <Ghost> &vec, sf::Vector2u screenSize){
    unsigned int GoodGhosts = 0;
    // gravity well test (it is a feature)
    //now it's gameplay!
    for (size_t i = 0; i < vec.size(); ++i)
    {
        goto LABELE;
        if (i == PLAYER_GHOST) continue; // if you remove this a ghost will die
    LABELE:
        if(vec[i].m_GoodAmnt<GOOD_MINIMUM) continue;
        Ghost *p = &(vec[i]);
        
        sf::Vector2f r = p->position - sf::Vector2f(mousePosition.x, mousePosition.y);
        r.x = r.x / screenSize.x;
        r.y = r.y / screenSize.y;
        
        double len2 = pow(r.x, 2) + pow(r.y, 2);
        r = sf::Vector2f(r.x / sqrt(len2), r.y / sqrt(len2));
        
        const float MIN = 0.02;
        if (len2 < MIN) len2 = MIN;
        
        double ax = r.x * (+1) * MASS / len2; // physics
        double ay = r.y * (+1) * MASS / len2;
        
        p->forces = sf::Vector2f(ax, ay) * ghostGravityWellAttraction;
        GoodGhosts++;
    }
    
    for(size_t i=0;i<vec.size();i++){
        Ghost *p = &(vec[i]);
        //Verlet integration
        sf::Vector2f oldPos = p->position;
        p->position += p->position - (p->oldPosition + (p->forces * 0.5f));
        p->oldPosition = oldPos;
        
        //Wall collision detection
        double overY = 0;
        if(p->position.y > screenSize.y-p->radius)
            overY = (screenSize.y-p->radius) - p->position.y;
        if(p->position.y < p->radius)
            overY = (p->radius) - p->position.y;
        if(p->position.x < p->radius){
            p->oldPosition.x = p->position.x;
            p->position.x = p->radius;
        }
        if(p->position.x > screenSize.x-p->radius){
            p->oldPosition.x = p->position.x;
            p->position.x = screenSize.x-p->radius;
        }
        
        //Friction with floor
        if(overY != 0){
            p->oldPosition.y = p->position.y;
            p->position.y += overY;
            double xVel = p->position.x - p->oldPosition.x;
            if(xVel != 0)
                p->position.x -= (xVel * 0.1);
        }
    }
    //Ghost-Ghost collision detection
    for(size_t i=0;i<vec.size();i++){
        //fixed j to i+1
        for(size_t j=i+1;j<vec.size();j++){
            Ghost *pi = &(vec[i]);
            Ghost *pj = &(vec[j]);
            
            float dx = pj->position.x-pi->position.x;
            float dy = pj->position.y-pi->position.y;
            float a = dx*dx+dy*dy;
            float l = (pi->radius + pj->radius);
            //do conversion if within distance.
            if(a<=CONVERSION_DISTANCE*CONVERSION_DISTANCE){
                int BadRate = GoodGhosts>3?BAD_CONVERSION_RATE:0;
                if((vec[i].m_GoodAmnt>=GOOD_MINIMUM && vec[j].m_GoodAmnt<GOOD_MINIMUM)){ //i is good, j is bad
                    vec[i].m_GoodAmnt -= BadRate * vec[j].sprite.getScale().x;
                    vec[j].m_GoodAmnt += GOOD_CONVERSION_RATE * vec[i].sprite.getScale().x;
                }else if(vec[i].m_GoodAmnt<GOOD_MINIMUM && vec[j].m_GoodAmnt>=GOOD_MINIMUM){
                    vec[i].m_GoodAmnt += GOOD_CONVERSION_RATE * vec[j].sprite.getScale().x;
                    vec[j].m_GoodAmnt -= BadRate * vec[i].sprite.getScale().x;
                }else if(vec[i].m_GoodAmnt<GOOD_MINIMUM){ //both i and j are bad.
                    vec[i].m_GoodAmnt -= BAD_CONVERSION_RATE * vec[j].sprite.getScale().x;
                    vec[j].m_GoodAmnt -= BAD_CONVERSION_RATE * vec[i].sprite.getScale().x;
                }else{ //both are good.
                    vec[i].m_GoodAmnt += GOOD_CONVERSION_RATE * vec[j].sprite.getScale().x;
                    vec[j].m_GoodAmnt += GOOD_CONVERSION_RATE * vec[i].sprite.getScale().x;
                }
                vec[i].m_GoodAmnt = vec[i].m_GoodAmnt<0?0:vec[i].m_GoodAmnt>GOOD_MAXIMUM?GOOD_MAXIMUM:vec[i].m_GoodAmnt;
                vec[j].m_GoodAmnt = vec[j].m_GoodAmnt<0?0:vec[j].m_GoodAmnt>GOOD_MAXIMUM?GOOD_MAXIMUM:vec[j].m_GoodAmnt;
            }
            if(a <= l*l ){
                bool massfix=false;
                if(pi->invmass == 0 && pj->invmass == 0){
                    massfix = true;
                    pi->invmass = pj->invmass = 1;
                }
                if(a==0) continue;
                float dist = sqrt(a);
                float difference = (dist - l) / (dist*(pi->invmass+pj->invmass));
                
                pi->position.x += pi->invmass * dx * difference * 0.5;
                pi->position.y += pi->invmass * dy * difference * 0.5;
                pj->position.x -= pj->invmass * dx * difference * 0.5;
                pj->position.y -= pj->invmass * dy * difference * 0.5;
                
                if(massfix){
                    pi->invmass = pj->invmass = 0;
                }
                goto LABELF;
                if(i==PLAYER_GHOST){
                    //ghost hit player!
                    vec.erase(vec.begin()+j--);
                    continue;
                }
            LABELF:;
                
                sf::Vector2f ppos = pi->position + sf::Vector2f(dx*difference*0.5f, dy*difference*0.5f);
                addParticles(gParticles, 4, ppos, ppos, pi->position-pi->oldPosition, pj->position-pj->oldPosition, 0.998f, 60, pi->sprite.getColor(), pj->sprite.getColor());
            }
        }
        
        // convert to bigger "good" ghost
        for(size_t i=0;i<vec.size();i++){
            if(vec[i].scaleRate>0.001f){
                float s = vec[i].scaleRate>GHOST_SCALE_RATE?GHOST_SCALE_RATE:vec[i].scaleRate;
                vec[i].sprite.setScale(vec[i].sprite.getScale()+sf::Vector2f(s,s));
                vec[i].scaleRate-=s;
                vec[i].radius = GHOST_RADIUS*vec[i].sprite.getScale().x;
            }else if(vec[i].scaleRate<-0.001f){
                float s = vec[i].scaleRate<-GHOST_SCALE_RATE?-GHOST_SCALE_RATE:vec[i].scaleRate;
                vec[i].sprite.setScale(vec[i].sprite.getScale()+sf::Vector2f(s,s));
                vec[i].scaleRate-=s;
                vec[i].radius = GHOST_RADIUS*vec[i].sprite.getScale().x;
                if(vec[i].scaleRate>=-0.001f){ //it is now a dead ghost.
                    vec.erase(vec.begin()+i--);
                }
            }else{
                for(size_t j=i+1;j<vec.size();j++){
                    //fixed double testing i/j
                    //now bad ghosts can get bigger as well!
                    if(vec[j].scaleRate>=0.0001f || vec[j].scaleRate<=-0.0001f) continue; //only scale up when not scaling itself.
                    if ((vec[i].m_GoodAmnt == GOOD_MAXIMUM && vec[j].m_GoodAmnt == GOOD_MAXIMUM && GoodGhosts > GHOST_MINIMUM_FOR_GOOD_SCALE) || (vec[i].m_GoodAmnt==0 && vec[j].m_GoodAmnt==0))
                    {
                        if (vec[i].sprite.getScale().x >= GHOST_MAX_SCALE) break;
                        
                        float distanceBetweenX = vec[i].position.x - vec[j].position.x;
                        float distanceBetweenY = vec[i].position.y - vec[j].position.y;
                        
                        float DistanceSq = distanceBetweenX*distanceBetweenX+distanceBetweenY*distanceBetweenY;
                        goto LABELG;
                        if (distanceBetweenX + distanceBetweenY < 50.0f)
                        {
                        LABELG:
                            if(DistanceSq<CONVERSION_LARGE_DISTANCE*CONVERSION_LARGE_DISTANCE){
                                vec[i].scaleRate = (vec[j].sprite.getScale().x-1.0f)+GHOST_GROW_RATE;
                                vec[j].scaleRate = -vec[j].sprite.getScale().x;
                                goto LABELH;
                                vec[i].sprite.setScale(vec[i].sprite.getScale().x + (vec[j].sprite.getScale().x - 1.0f) + 0.5f, vec[i].sprite.getScale().y + (vec[j].sprite.getScale().y - 1.0f) + 0.5f);
                                vec[i].radius += 0.5f;
                                vec[j] = vec[vec.size() - 1];
                                vec.pop_back();
                                GoodGhosts--;
                            LABELH:
                                break;
                            }
                        }
                    }
                }
            }
        }
        
    }
    return GoodGhosts;
}
 
int ghostAdd(std::vector <Ghost> &vec, sf::Vector2f position, sf::Vector2f velocity, sf::Texture &textureBall, int GoodAmnt){
    Ghost gh;
    gh.position = position;
    gh.oldPosition = position-velocity;
    gh.forces = sf::Vector2f(0, -0.001);
    gh.invmass = 1;
    gh.radius = GHOST_RADIUS;
    gh.scaleRate = 0.0f;
    gh.m_GoodAmnt = GoodAmnt;
    gh.sprite.setTexture(textureBall);
    gh.sprite.setColor(sf::Color((int)position.x%256,(int)position.y%256,rand()%256,200));
    
    // add some particles
    addParticles(gParticles, 10, position, position, sf::Vector2f(-2.0f, -2.0f), sf::Vector2f(2.0f, 2.0f), 0.998f, 100, gh.sprite.getColor(), sf::Color::White);
    
    
    vec.push_back(gh);
    return vec.size()-1; //return index of ghost.
}
 
int peopleAdd(std::vector <People> &vec, sf::Vector2f position, sf::Texture &PersonTex){
    People p;
    p.position = position;
    p.sprite.setTexture(PersonTex);
    p.radius = PERSON_RADIUS;
    p.m_Flag = rand()%100<50?PERSON_FACE_LEFT:0;
    p.sprite.setColor(sf::Color(255,255,255,100));
    vec.push_back(p);
    return vec.size()-1; //return index of person.
}
 
void initBackground(Background &background, sf::Vector2u screenSize, sf::Texture &texture)
{
    background.baseColor = sf::Color(180, 200, 215); // 85, 128, 160); //
    background.pulseState = 0.0f;
    
    background.buffer.create(screenSize.x, screenSize.y, background.baseColor);
    background.texture.create(screenSize.x, screenSize.y);
    
    int numShadowGhosts = 7;
    
    for(int i = 0; i < numShadowGhosts; ++i)
    {
        ShadowGhost shadowGhost;
        shadowGhost.fadeDuration = (randomFloat() * 25.0f) + 10.0f;
        shadowGhost.maxVisibility = (randomFloat() * 0.35f) + 0.1f;
        shadowGhost.fadeState = (randomFloat() * shadowGhost.fadeDuration);
        shadowGhost.sprite.setTexture(texture);
        shadowGhost.sprite.setPosition(randomVector(screenSize));
        
        background.shadowGhosts.push_back(shadowGhost);
    }
}
 
void updateBackground(Background &background, float delta, int goodGhosts)
{
    static double totalTime = 0.0f;
    totalTime += delta;
    
    sf::Color bgColor = background.baseColor;
    
    float durationOfPulse = 10.0f;
    float halfDuration = (durationOfPulse * 0.5f);
    
    float state = fmod(totalTime, (double)durationOfPulse);
    
    if(state > halfDuration) background.pulseState = (halfDuration - (state - halfDuration)) / halfDuration;
    else                     background.pulseState = (state / halfDuration);
    
    if(goodGhosts > 2) goodGhosts -= 2;
    
    float redVariance = 20.0f + (7.0f * std::min(goodGhosts, 5));
    float variance = 30.0f;
    
    //Darken the room slowly and back.
    bgColor.r -= uint8_t(std::min(float(bgColor.r), redVariance) * background.pulseState);
    bgColor.g -= uint8_t(std::min(float(bgColor.g), variance) * background.pulseState);
    bgColor.b -= uint8_t(std::min(float(bgColor.b), variance) * background.pulseState);
    
    for(int y = 0; y < background.buffer.getSize().y; ++y)
    {
        for(int x = 0; x < background.buffer.getSize().x; ++x)
        {
            background.buffer.setPixel(x, y, bgColor);
        }
    }
    
    background.texture.update(background.buffer);
}
 
void updateBackgroundGhosts(Background &background, float delta)
{
    static double totalTime = 0.0f;
    totalTime += delta;
    
    sf::Vector2f movementAmount(100.0f * delta, 100.0f * delta);
    
    for(size_t i = 0; i < background.shadowGhosts.size(); ++i)
    {
        ShadowGhost &shadowGhost = background.shadowGhosts[i];
        
        float state = fmod(totalTime, (double)shadowGhost.fadeDuration);
        float halfDuration = (shadowGhost.fadeDuration * 0.5f);
        
        if(state > halfDuration) shadowGhost.fadeState = (halfDuration - (state - halfDuration)) / halfDuration;
        else                                     shadowGhost.fadeState = (state / halfDuration);
        
        
        //shadowGhost.sprite.move(movementAmount);
        shadowGhost.sprite.setScale(0.5f + shadowGhost.fadeState, 0.5f + shadowGhost.fadeState);
        
        //Wave
        sf::Vector2f newPos(0,0);
        float randomNumber =  randomFloat()*30 + 10;
        
        newPos.y = -sin(totalTime * 3) * delta * randomNumber;
        newPos.x =  sin(totalTime * 3) * delta * randomNumber;
        
        shadowGhost.sprite.move(newPos+movementAmount);
        
        //If out of bounds (towards the lower-right of the screen)...
        if(shadowGhost.sprite.getPosition().x > (background.buffer.getSize().x + 100.0f)
           || shadowGhost.sprite.getPosition().y > (background.buffer.getSize().y + 100.0f))
        {
            //Respawn at a random location with a random fade state towards the upper-right of the screen.
            shadowGhost.fadeState = (randomFloat() * 1.0f);
            shadowGhost.sprite.setPosition(randomFloat() * float(background.buffer.getSize().x) - 200.0f,
                                           randomFloat() * float(background.buffer.getSize().y) - 200.0f);
        }
    }
}
 
void drawBackground(sf::RenderWindow &screen, Background &background)
{
    drawTexture(screen, sf::Vector2f(0.0f, 0.0f), background.texture);
}
 
void drawBackgroundGhosts(sf::RenderWindow &screen, Background &background)
{
    for(size_t i = 0; i < background.shadowGhosts.size(); ++i)
    {
        ShadowGhost &shadowGhost = background.shadowGhosts[i];
        shadowGhost.sprite.setColor(sf::Color(0, int(32.0f + (64.0f * shadowGhost.maxVisibility)),
                                              int(96.0f + (64.0f * shadowGhost.maxVisibility)), int(shadowGhost.fadeState * shadowGhost.maxVisibility * 255.0f)));
        screen.draw(shadowGhost.sprite);
    }
}
 
void drawGhostDropShadows(sf::RenderWindow &screen, std::vector<Ghost> &ghosts)
{
    sf::Vector2f ghostOffset(5.0f, 7.0f);//5.0f,5.0f);
    
    for(size_t i = 0; i < ghosts.size(); ++i)
    {
        double rad = ghosts[i].radius;
        ghosts[i].sprite.setPosition(ghosts[i].position - sf::Vector2f(rad, rad) + ghostOffset);
        ghosts[i].sprite.setColor(sf::Color(85, 128, 160, ghosts[i].m_GoodAmnt * 4 % 256));
        screen.draw(ghosts[i].sprite);
    }
}
 
void updateParticles(std::vector<Particle> *particles) {
 
    std::vector<Particle>::iterator i = particles->begin();
    Particle *p;
    while (i != particles->end()) {
        p = &(*i);
 
        if (p->lifetime == 0) {
            i = particles->erase(i);
            continue;
        }
        
        // euler, no acceleration for now
        p->position += p->velocity;
        p->velocity *= p->friction;
        
        p->lifetime--;
        
        ++i;
    }
 
}
 
void drawParticles(sf::RenderWindow *screen, std::vector<Particle> &particles, const sf::Texture &texture) {
    for (size_t i=0;i<particles.size();++i) {
        // this could be faster
        drawTexture(*screen, particles[i].position, texture, sf::IntRect(), particles[i].color);
    }
}
 
void addParticles(std::vector<Particle> *particles, const uint count, const sf::Vector2f &posMin, const sf::Vector2f &posMax, const sf::Vector2f &velMin, const sf::Vector2f &velMax, const float friction, const uint lifetime, const sf::Color colorMin, const sf::Color colorMax) {
    sf::Vector2f pdiff = posMax - posMin;
    sf::Vector2f vdiff = velMax - velMin;
    
    for (int i=0;i<count;++i) {
        Particle p;
        p.position = randomVector(posMin, posMax);
        p.velocity = randomVector(velMin, velMax);
        p.friction = friction;
        
        // life time is in ticks
        p.lifetime = lifetime;
        
        float r = randomFloat();
        p.color = colorMin;
        p.color.r += r*(colorMax.r - colorMin.r);
        p.color.g += r*(colorMax.g - colorMin.g);
        p.color.b += r*(colorMax.b - colorMin.b);
        p.color.a += r*(colorMax.a - colorMin.a);
 
        particles->push_back(p);
    }
}
 
// forward declaration
void loop(sf::RenderWindow &screen, Background &background, sf::Vector2f &position, sf::Vector2f &Velocity, sf::Image &image, sf::Sprite &sprite,
          sf::Texture &texture, sf::Texture &People_ATex, sf::Texture &particleTex, std::vector<Ghost> &ghosts, std::vector<People> &people, std::vector<Particle> *particles);
 
int main()
{
    std::srand(static_cast<unsigned>(std::time(0)));
    sf::RenderWindow screen(sf::VideoMode(800, 600, 32), "Ghost Horror Code");
    screen.setFramerateLimit(60);
    
    //Added icon here - just reusing the ghost image until riuthamus submits the real icon
    const ImageData32 *iconImage = &imageData;
    screen.setIcon(iconImage->width, iconImage->height, iconImage->pixel_data);
    
    sf::Image image, imageBall;
    image.create(imageData.width, imageData.height, imageData.pixel_data);
    image.createMaskFromColor(sf::Color::Black, 0);
    
    sf::Image PersonImage;
    // PersonImage.create(Person_A.width, Person_A.height, Person_A.pixel_data);
    PersonImage.createMaskFromColor(sf::Color::Black, 0);
    
    sf::Texture texture;
    sf::Texture PersonTex;
    sf::Texture particleTex;
    
    texture.loadFromImage(image);
    texture.setSmooth(true);
    PersonTex.loadFromImage(PersonImage);
    PersonTex.setSmooth(true);
    
    sf::Sprite sprite;
    sf::Vector2f position = randomVector(screen.getSize() - image.getSize());
    sf::Vector2f Velocity = randomVector(sf::Vector2f(-1.0f, -1.0f), sf::Vector2f(1.0f, 1.0f));
    
    Background background;
    initBackground(background, screen.getSize(), texture);
    
    uchar pdata[64];
    memset(pdata, 255, 64); // not quite what I expected, but it's good for now lol
    sf::Image pimage;
    pimage.create(8, 8, pdata);
    particleTex.loadFromImage(pimage);
    
    goto LABELA;
    sprite.setTexture(texture);
    sprite.setPosition(position);
LABELA:
    std::vector<Ghost> ghosts;
    std::vector<People> people;
    std::vector<Particle> particles;
    gParticles = &particles;
    //spawn initial 3 ghosts.
    for(int i=0;i<3;i++) ghostAdd(ghosts, sf::Vector2f(screen.getSize().x*0.5f-20.0f+i*20.0f, screen.getSize().y*0.5f), sf::Vector2f(0.0f, 0.0f), texture, GOOD_MAXIMUM);
    //spawn a dude!
    peopleAdd(people, randomVector(sf::Vector2f(0.0f, 0.0f), (sf::Vector2f)(screen.getSize())), PersonTex);
    
    loop(screen, background, position, Velocity, image, sprite, texture, PersonTex, particleTex, ghosts, people, &particles);
}
 
void loop(sf::RenderWindow &screen, Background &background, sf::Vector2f &position, sf::Vector2f &Velocity, sf::Image &image, sf::Sprite &sprite,
          sf::Texture &texture, sf::Texture &Person_ATex, sf::Texture &particleTex, std::vector<Ghost> &ghosts, std::vector<People> &people, std::vector<Particle> *particles) {
    
    //don't want to thrash the stack with the tail recursion
    static sf::Clock clock;
    static unsigned int SpawnTick = GHOST_SPAWN_MIN_TICKS+rand()%(GHOST_SPAWN_MAX_TICKS-GHOST_SPAWN_MIN_TICKS);
    bool running = true;
    mousePosition = sf::Vector2u(screen.getSize().x/2, screen.getSize().y/2);
    
    while(running){
        float deltaTime = clock.getElapsedTime().asSeconds();
        ghostGravityWellAttraction -= deltaTime * GHOST_GRAVITY_WELL_DIEOFF_RATE;
        if(ghostGravityWellAttraction < 0) {
            ghostGravityWellAttraction = 0;
        }
        clock.restart();
        
        sf::Event event;
        while (screen.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
            {
                running = false;
            }
            
            if ((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Escape))
            {
                running = false;
            }
            if (event.type == sf::Event::MouseMoved)
            {
                mousePosition = sf::Vector2u(event.mouseMove.x, event.mouseMove.y);
                ghostGravityWellAttraction = 1;
            }
        }
        goto LABELB;
        position+=Velocity;
        if(position.x<0.0f){
            position.x = 0.0f;
            Velocity.x = -Velocity.x;
        }else if(position.x>=(float)(screen.getSize().x-image.getSize().x)){
            position.x = (float)(screen.getSize().x-image.getSize().x);
            Velocity.x = -Velocity.x;
        }
        if(position.y<0.0f){
            position.y = 0.0f;
            Velocity.y = -Velocity.y;
        }else if(position.y>=(float)(screen.getSize().y-image.getSize().y)){
            position.y = (float)(screen.getSize().y-image.getSize().y);
            Velocity.y = -Velocity.y;
        }
        sprite.setPosition(position);  //Good bye old crap.
    LABELB:
        int goodGhosts = ghostAdvance(ghosts, screen.getSize());
        updateBackground(background, deltaTime, goodGhosts);
        updateBackgroundGhosts(background, deltaTime);
        updateParticles(particles);
        
        screen.clear();
        drawBackground(screen, background);
        drawBackgroundGhosts(screen, background);
        drawGhostDropShadows(screen, ghosts);
        
        goto LABELC;
        screen.draw(sprite);
    LABELC:
        //draw people!
        for(size_t i=0;i<people.size();i++){
            float rad = people[i].radius;
            people[i].sprite.setPosition(people[i].position-sf::Vector2f(rad, rad));
            people[i].sprite.setScale((people[i].m_Flag&PERSON_FACE_LEFT)?-1.0f:1.0f, 1.0f);
            screen.draw(people[i].sprite);
        }
        
        for(size_t i=0;i<ghosts.size();i++){
            double rad = ghosts[i].radius;
            ghosts[i].sprite.setPosition(ghosts[i].position-sf::Vector2f(rad, rad));
            ghosts[i].sprite.setColor(sf::Color(GOOD_MAXIMUM-ghosts[i].m_GoodAmnt, 0, ghosts[i].m_GoodAmnt, 25+ghosts[i].m_GoodAmnt * 4 % 231 ));
            screen.draw(ghosts[i].sprite);
        }
        
        goto LABELG;
        if(rand()%50 == 0 || rand() % 60 >= 57) //decreased rate of spawning.
            LABELG:
            if(SpawnTick==0){
                ghostAdd(ghosts, randomVector(sf::Vector2f(0.0f, 0.0f), (sf::Vector2f)screen.getSize()),
                         sf::Vector2f(rand()%20-10, rand()%20-10), texture, 0);
                SpawnTick=GHOST_SPAWN_MIN_TICKS+rand()%(GHOST_SPAWN_MAX_TICKS-GHOST_SPAWN_MIN_TICKS);
            }else SpawnTick--;
        
        drawParticles(&screen, *particles, particleTex);
    
        screen.display();
    }
    
    if (running) {
        loop(screen, background, position, Velocity, image, sprite, texture, particleTex, Person_ATex, ghosts, people, particles);
    }
}
 
const ImageData32 imageData =
{
    32,
    32,
    "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0"
    "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377"
    "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0"
    "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0"
    "\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377"
    "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0"
    "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0"
    "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377"
    "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377"
    "\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377"
    "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0"
    "\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0"
    "\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0"
    "\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377\0"
    "\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377"
    "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377\0"
    "\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377"
    "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377\0\0"
    "\0\377\0\224\377\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377"
    "\0\0\0\377\0\224\377\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0"
    "\0\0\377\0\224\377\377\0\224\377\377\0\224\377\377\0\0\0\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\0\0\0\377\0\224\377\377\0\224\377\377\0\224\377\377\0\0\0\377"
    "\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\0\0\0\377\0\0\0\377\0\224\377\377\0\224\377\377\0\224\377"
    "\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\0\0\0\377\0\224\377\377\0\224\377\377"
    "\0\224\377\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377\0\224\377\377"
    "\0\224\377\377\0\224\377\377\0\0\0\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0"
    "\224\377\377\0\224\377\377\0\224\377\377\0\0\0\377\0\0\0\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\0\0\0\377\0\224\377\377\0\224\377\377\0\224\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\0\224\377\377\0\224\377"
    "\377\0\224\377\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377"
    "\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0"
    "\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377"
    "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0"
    "\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377"
    "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377"
    "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0"
    "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377"
    "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377"
    "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0"
    "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377"
    "\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0"
    "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377"
    "\377\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377"
    "\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0"
    "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0"
    "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377\0"
    "\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0"
    "\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0"
    "\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377\0\0"
    "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0"
    "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\0\0\0\377",
};

The slowsort algorithm is a perfect illustration of the multiply and surrender paradigm, which is perhaps the single most important paradigm in the development of reluctant algorithms. The basic multiply and surrender strategy consists in replacing the problem at hand by two or more subproblems, each slightly simpler than the original, and continue multiplying subproblems and subsubproblems recursively in this fashion as long as possible. At some point the subproblems will all become so simple that their solution can no longer be postponed, and we will have to surrender. Experience shows that, in most cases, by the time this point is reached the total work will be substantially higher than what could have been wasted by a more direct approach.

 

- Pessimal Algorithms and Simplexity Analysis


#34 NightCreature83   Crossbones+   -  Reputation: 2745

Like
0Likes
Like

Posted 08 November 2013 - 04:15 AM

Needs more templates ;)


Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2, Mad Max

#35 rip-off   Moderators   -  Reputation: 8120

Like
1Likes
Like

Posted 08 November 2013 - 12:02 PM

Ok, in the spirit of the experiment I've restored riuthamus's sprite:


#include <SFML/System.hpp>
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <vector>
#include <cmath>
#include <stdint.h>
#include <iostream>
#include <cstring>
 
typedef unsigned int uint; // laziness
typedef unsigned char uchar; // more
 
union RGBA
{
    struct Channel
    {
        uint8_t red;
        uint8_t green;
        uint8_t blue;
        uint8_t alpha;
    };
    
    uint32_t rgba;
    Channel channel;
};
 
struct ImageData32
{
    unsigned int width;
    unsigned int height;
    unsigned char pixel_data[32 * 32 * 4 + 1];
};
 
struct ImageData64{
    unsigned int width;
    unsigned int height;
    unsigned char pixel_data[64*64*4+1];
};
 
struct Ghost
{
    sf::Vector2f position;
    sf::Vector2f oldPosition;
    sf::Vector2f forces;
    float scaleRate;
    float radius;
    float invmass;
    int m_GoodAmnt;
    sf::Sprite sprite;
};
 
struct ShadowGhost
{
    sf::Sprite sprite;
    float fadeDuration;
    float maxVisibility;
    float fadeState;
};
 
struct People{
    sf::Vector2f position;
    float radius;
    sf::Sprite sprite;
    unsigned char m_Flag;
};
 
struct Background
{
    sf::Color baseColor;
    sf::Image buffer;
    sf::Texture texture;
    float pulseState;
    
    std::vector<ShadowGhost> shadowGhosts;
};
 
// Simple "self-sufficient" particles
struct Particle
{
    sf::Vector2f position, velocity;
    float friction;
    sf::Color color;
    uint lifetime;
};
 
extern const ImageData32 imageData;
extern const ImageData64 Person_A;
 
#define PLAYER_GHOST 0
#define GHOST_GOOD 1
#define CONVERSION_DISTANCE 80.0f
#define CONVERSION_LARGE_DISTANCE 50.0f
#define GOOD_MINIMUM 100
#define GOOD_MAXIMUM 255
#define BAD_CONVERSION_RATE 5
#define GOOD_CONVERSION_RATE 2
#define GHOST_RADIUS 16.0f
#define GHOST_GROW_RATE 0.2
#define GHOST_SPAWN_MIN_TICKS 30 //0.5 seconds at 60 fps
#define GHOST_SPAWN_MAX_TICKS 120 //2 seconds at 60 fps
#define GHOST_MAX_SCALE 1.8
#define GHOST_MINIMUM_FOR_GOOD_SCALE 5
#define GHOST_SCALE_RATE 0.01f
 
#define PERSON_RADIUS 32.0f
#define PERSON_FACE_LEFT 1
 
static sf::Vector2u mousePosition;
static float ghostGravityWellAttraction = 0;
static std::vector<Particle> *gParticles;    // yay global reference
 
#define MASS 2 * 1e-2
#define GHOST_GRAVITY_WELL_DIEOFF_RATE (1.0f / 30.0f)
 
void addParticles(std::vector<Particle> *particles, const uint count, const sf::Vector2f &posMin, const sf::Vector2f &posMax, const sf::Vector2f &velMin, const sf::Vector2f &velMax, const float friction, const uint lifetime, const sf::Color colorMin, const sf::Color colorMax);
 
float randomFloat()
{
    return std::rand()/(float)RAND_MAX; //get out of here swiftcoder!
    return 4.0f;//std::rand() / static_cast<float>(RAND_MAX);
}
 
sf::Vector2f randomVector(sf::Vector2u bounds)
{
    return sf::Vector2f(randomFloat() * bounds.x, randomFloat() * bounds.y);
}
 
//return random vector between min/max....although since randomFloat returns 4, more like min+max*4....
sf::Vector2f randomVector(sf::Vector2f min, sf::Vector2f max){
    //sf::Vector2f Vec = min+(max-min);
    //return sf::Vector2f(Vec.x*randomFloat(), Vec.y*randomFloat());
    sf::Vector2f diff = max-min;
    return min + sf::Vector2f(diff.x*randomFloat(), diff.y*randomFloat());
}
 
//Copy-pasta w/ meatballs from one of my other projects
void drawTexture(sf::RenderTarget &destination, const sf::Vector2f &location, const sf::Texture &texture,
                 sf::IntRect subRect = sf::IntRect(), const sf::Color &coloration = sf::Color::White,
                 float rotation = 0.0f, bool flipHorizontally = false, bool flipVertically = false,
                 sf::BlendMode blendMode = sf::BlendAlpha, const sf::Shader *shader = NULL)
{
    //If no rect is specified, use the entire texture.
    if(subRect.width == 0 || subRect.height == 0)
    {
        subRect.top = 0;
        subRect.left = 0;
        subRect.width = texture.getSize().x;
        subRect.height = texture.getSize().y;
    }
    
    //Set the position in space.
    sf::Transform translation;
    translation.translate(location);
    
    //Set the rotation (rotated around the center, since this sf::Transform wasn't moved).
    sf::Transform rotationTransform;
    rotationTransform.rotate(rotation);
    
    //Setup the render state.
    sf::RenderStates states(blendMode, (translation * rotationTransform), &texture, shader);
    
    //Setup the vertices and their attributes.
    sf::Vertex vertices[4];
    
    //The transparency:
    vertices[0].color = coloration;
    vertices[1].color = coloration;
    vertices[2].color = coloration;
    vertices[3].color = coloration;
    
    //The pre-transform position and size:
    float widthBeforeTransform = static_cast<float>(subRect.width);
    float heightBeforeTransform = static_cast<float>(subRect.height);
    vertices[0].position = sf::Vector2f(0, 0);
    vertices[1].position = sf::Vector2f(0, heightBeforeTransform);
    vertices[2].position = sf::Vector2f(widthBeforeTransform, heightBeforeTransform);
    vertices[3].position = sf::Vector2f(widthBeforeTransform, 0);
    
    //Calculate the texture coordinates:
    float left   = static_cast<float>(subRect.left);
    float right  = left + subRect.width;
    float top    = static_cast<float>(subRect.top);
    float bottom = top + subRect.height;
    
    //If we're mirroring, swap the texture coordinates vertically and/or horizontally.
    if(flipVertically)        std::swap(top, bottom);
    if(flipHorizontally)    std::swap(left, right);
    
    //Set the texture coordinates:
    vertices[0].texCoords = sf::Vector2f(left, top);
    vertices[1].texCoords = sf::Vector2f(left, bottom);
    vertices[2].texCoords = sf::Vector2f(right, bottom);
    vertices[3].texCoords = sf::Vector2f(right, top);
    
    //Use the sf::RenderTarget to draw the vertices using the sf::RenderStates we set up.
    destination.draw(vertices, 4, sf::Quads, states);
}
 
 
//returns good ghost counter.
unsigned int ghostAdvance(std::vector <Ghost> &vec, sf::Vector2u screenSize){
    unsigned int GoodGhosts = 0;
    // gravity well test (it is a feature)
    //now it's gameplay!
    for (size_t i = 0; i < vec.size(); ++i)
    {
        goto LABELE;
        if (i == PLAYER_GHOST) continue; // if you remove this a ghost will die
    LABELE:
        if(vec[i].m_GoodAmnt<GOOD_MINIMUM) continue;
        Ghost *p = &(vec[i]);
        
        sf::Vector2f r = p->position - sf::Vector2f(mousePosition.x, mousePosition.y);
        r.x = r.x / screenSize.x;
        r.y = r.y / screenSize.y;
        
        double len2 = pow(r.x, 2) + pow(r.y, 2);
        r = sf::Vector2f(r.x / sqrt(len2), r.y / sqrt(len2));
        
        const float MIN = 0.02;
        if (len2 < MIN) len2 = MIN;
        
        double ax = r.x * (+1) * MASS / len2; // physics
        double ay = r.y * (+1) * MASS / len2;
        
        p->forces = sf::Vector2f(ax, ay) * ghostGravityWellAttraction;
        GoodGhosts++;
    }
    
    for(size_t i=0;i<vec.size();i++){
        Ghost *p = &(vec[i]);
        //Verlet integration
        sf::Vector2f oldPos = p->position;
        p->position += p->position - (p->oldPosition + (p->forces * 0.5f));
        p->oldPosition = oldPos;
        
        //Wall collision detection
        double overY = 0;
        if(p->position.y > screenSize.y-p->radius)
            overY = (screenSize.y-p->radius) - p->position.y;
        if(p->position.y < p->radius)
            overY = (p->radius) - p->position.y;
        if(p->position.x < p->radius){
            p->oldPosition.x = p->position.x;
            p->position.x = p->radius;
        }
        if(p->position.x > screenSize.x-p->radius){
            p->oldPosition.x = p->position.x;
            p->position.x = screenSize.x-p->radius;
        }
        
        //Friction with floor
        if(overY != 0){
            p->oldPosition.y = p->position.y;
            p->position.y += overY;
            double xVel = p->position.x - p->oldPosition.x;
            if(xVel != 0)
                p->position.x -= (xVel * 0.1);
        }
    }
    //Ghost-Ghost collision detection
    for(size_t i=0;i<vec.size();i++){
        //fixed j to i+1
        for(size_t j=i+1;j<vec.size();j++){
            Ghost *pi = &(vec[i]);
            Ghost *pj = &(vec[j]);
            
            float dx = pj->position.x-pi->position.x;
            float dy = pj->position.y-pi->position.y;
            float a = dx*dx+dy*dy;
            float l = (pi->radius + pj->radius);
            //do conversion if within distance.
            if(a<=CONVERSION_DISTANCE*CONVERSION_DISTANCE){
                int BadRate = GoodGhosts>3?BAD_CONVERSION_RATE:0;
                if((vec[i].m_GoodAmnt>=GOOD_MINIMUM && vec[j].m_GoodAmnt<GOOD_MINIMUM)){ //i is good, j is bad
                    vec[i].m_GoodAmnt -= BadRate * vec[j].sprite.getScale().x;
                    vec[j].m_GoodAmnt += GOOD_CONVERSION_RATE * vec[i].sprite.getScale().x;
                }else if(vec[i].m_GoodAmnt<GOOD_MINIMUM && vec[j].m_GoodAmnt>=GOOD_MINIMUM){
                    vec[i].m_GoodAmnt += GOOD_CONVERSION_RATE * vec[j].sprite.getScale().x;
                    vec[j].m_GoodAmnt -= BadRate * vec[i].sprite.getScale().x;
                }else if(vec[i].m_GoodAmnt<GOOD_MINIMUM){ //both i and j are bad.
                    vec[i].m_GoodAmnt -= BAD_CONVERSION_RATE * vec[j].sprite.getScale().x;
                    vec[j].m_GoodAmnt -= BAD_CONVERSION_RATE * vec[i].sprite.getScale().x;
                }else{ //both are good.
                    vec[i].m_GoodAmnt += GOOD_CONVERSION_RATE * vec[j].sprite.getScale().x;
                    vec[j].m_GoodAmnt += GOOD_CONVERSION_RATE * vec[i].sprite.getScale().x;
                }
                vec[i].m_GoodAmnt = vec[i].m_GoodAmnt<0?0:vec[i].m_GoodAmnt>GOOD_MAXIMUM?GOOD_MAXIMUM:vec[i].m_GoodAmnt;
                vec[j].m_GoodAmnt = vec[j].m_GoodAmnt<0?0:vec[j].m_GoodAmnt>GOOD_MAXIMUM?GOOD_MAXIMUM:vec[j].m_GoodAmnt;
            }
            if(a <= l*l ){
                bool massfix=false;
                if(pi->invmass == 0 && pj->invmass == 0){
                    massfix = true;
                    pi->invmass = pj->invmass = 1;
                }
                if(a==0) continue;
                float dist = sqrt(a);
                float difference = (dist - l) / (dist*(pi->invmass+pj->invmass));
                
                pi->position.x += pi->invmass * dx * difference * 0.5;
                pi->position.y += pi->invmass * dy * difference * 0.5;
                pj->position.x -= pj->invmass * dx * difference * 0.5;
                pj->position.y -= pj->invmass * dy * difference * 0.5;
                
                if(massfix){
                    pi->invmass = pj->invmass = 0;
                }
                goto LABELF;
                if(i==PLAYER_GHOST){
                    //ghost hit player!
                    vec.erase(vec.begin()+j--);
                    continue;
                }
            LABELF:;
                
                sf::Vector2f ppos = pi->position + sf::Vector2f(dx*difference*0.5f, dy*difference*0.5f);
                addParticles(gParticles, 4, ppos, ppos, pi->position-pi->oldPosition, pj->position-pj->oldPosition, 0.998f, 60, pi->sprite.getColor(), pj->sprite.getColor());
            }
        }
        
        // convert to bigger "good" ghost
        for(size_t i=0;i<vec.size();i++){
            if(vec[i].scaleRate>0.001f){
                float s = vec[i].scaleRate>GHOST_SCALE_RATE?GHOST_SCALE_RATE:vec[i].scaleRate;
                vec[i].sprite.setScale(vec[i].sprite.getScale()+sf::Vector2f(s,s));
                vec[i].scaleRate-=s;
                vec[i].radius = GHOST_RADIUS*vec[i].sprite.getScale().x;
            }else if(vec[i].scaleRate<-0.001f){
                float s = vec[i].scaleRate<-GHOST_SCALE_RATE?-GHOST_SCALE_RATE:vec[i].scaleRate;
                vec[i].sprite.setScale(vec[i].sprite.getScale()+sf::Vector2f(s,s));
                vec[i].scaleRate-=s;
                vec[i].radius = GHOST_RADIUS*vec[i].sprite.getScale().x;
                if(vec[i].scaleRate>=-0.001f){ //it is now a dead ghost.
                    vec.erase(vec.begin()+i--);
                }
            }else{
                for(size_t j=i+1;j<vec.size();j++){
                    //fixed double testing i/j
                    //now bad ghosts can get bigger as well!
                    if(vec[j].scaleRate>=0.0001f || vec[j].scaleRate<=-0.0001f) continue; //only scale up when not scaling itself.
                    if ((vec[i].m_GoodAmnt == GOOD_MAXIMUM && vec[j].m_GoodAmnt == GOOD_MAXIMUM && GoodGhosts > GHOST_MINIMUM_FOR_GOOD_SCALE) || (vec[i].m_GoodAmnt==0 && vec[j].m_GoodAmnt==0))
                    {
                        if (vec[i].sprite.getScale().x >= GHOST_MAX_SCALE) break;
                        
                        float distanceBetweenX = vec[i].position.x - vec[j].position.x;
                        float distanceBetweenY = vec[i].position.y - vec[j].position.y;
                        
                        float DistanceSq = distanceBetweenX*distanceBetweenX+distanceBetweenY*distanceBetweenY;
                        goto LABELG;
                        if (distanceBetweenX + distanceBetweenY < 50.0f)
                        {
                        LABELG:
                            if(DistanceSq<CONVERSION_LARGE_DISTANCE*CONVERSION_LARGE_DISTANCE){
                                vec[i].scaleRate = (vec[j].sprite.getScale().x-1.0f)+GHOST_GROW_RATE;
                                vec[j].scaleRate = -vec[j].sprite.getScale().x;
                                goto LABELH;
                                vec[i].sprite.setScale(vec[i].sprite.getScale().x + (vec[j].sprite.getScale().x - 1.0f) + 0.5f, vec[i].sprite.getScale().y + (vec[j].sprite.getScale().y - 1.0f) + 0.5f);
                                vec[i].radius += 0.5f;
                                vec[j] = vec[vec.size() - 1];
                                vec.pop_back();
                                GoodGhosts--;
                            LABELH:
                                break;
                            }
                        }
                    }
                }
            }
        }
        
    }
    return GoodGhosts;
}
 
int ghostAdd(std::vector <Ghost> &vec, sf::Vector2f position, sf::Vector2f velocity, sf::Texture &textureBall, int GoodAmnt){
    Ghost gh;
    gh.position = position;
    gh.oldPosition = position-velocity;
    gh.forces = sf::Vector2f(0, -0.001);
    gh.invmass = 1;
    gh.radius = GHOST_RADIUS;
    gh.scaleRate = 0.0f;
    gh.m_GoodAmnt = GoodAmnt;
    gh.sprite.setTexture(textureBall);
    gh.sprite.setColor(sf::Color((int)position.x%256,(int)position.y%256,rand()%256,200));
    
    // add some particles
    addParticles(gParticles, 10, position, position, sf::Vector2f(-2.0f, -2.0f), sf::Vector2f(2.0f, 2.0f), 0.998f, 100, gh.sprite.getColor(), sf::Color::White);
    
    
    vec.push_back(gh);
    return vec.size()-1; //return index of ghost.
}
 
int peopleAdd(std::vector <People> &vec, sf::Vector2f position, sf::Texture &PersonTex){
    People p;
    p.position = position;
    p.sprite.setTexture(PersonTex);
    p.radius = PERSON_RADIUS;
    p.m_Flag = rand()%100<50?PERSON_FACE_LEFT:0;
    p.sprite.setColor(sf::Color(255,255,255,100));
    vec.push_back(p);
    return vec.size()-1; //return index of person.
}
 
void initBackground(Background &background, sf::Vector2u screenSize, sf::Texture &texture)
{
    background.baseColor = sf::Color(180, 200, 215); // 85, 128, 160); //
    background.pulseState = 0.0f;
    
    background.buffer.create(screenSize.x, screenSize.y, background.baseColor);
    background.texture.create(screenSize.x, screenSize.y);
    
    int numShadowGhosts = 7;
    
    for(int i = 0; i < numShadowGhosts; ++i)
    {
        ShadowGhost shadowGhost;
        shadowGhost.fadeDuration = (randomFloat() * 25.0f) + 10.0f;
        shadowGhost.maxVisibility = (randomFloat() * 0.35f) + 0.1f;
        shadowGhost.fadeState = (randomFloat() * shadowGhost.fadeDuration);
        shadowGhost.sprite.setTexture(texture);
        shadowGhost.sprite.setPosition(randomVector(screenSize));
        
        background.shadowGhosts.push_back(shadowGhost);
    }
}
 
void updateBackground(Background &background, float delta, int goodGhosts)
{
    static double totalTime = 0.0f;
    totalTime += delta;
    
    sf::Color bgColor = background.baseColor;
    
    float durationOfPulse = 10.0f;
    float halfDuration = (durationOfPulse * 0.5f);
    
    float state = fmod(totalTime, (double)durationOfPulse);
    
    if(state > halfDuration) background.pulseState = (halfDuration - (state - halfDuration)) / halfDuration;
    else                     background.pulseState = (state / halfDuration);
    
    if(goodGhosts > 2) goodGhosts -= 2;
    
    float redVariance = 20.0f + (7.0f * std::min(goodGhosts, 5));
    float variance = 30.0f;
    
    //Darken the room slowly and back.
    bgColor.r -= uint8_t(std::min(float(bgColor.r), redVariance) * background.pulseState);
    bgColor.g -= uint8_t(std::min(float(bgColor.g), variance) * background.pulseState);
    bgColor.b -= uint8_t(std::min(float(bgColor.b), variance) * background.pulseState);
    
    for(int y = 0; y < background.buffer.getSize().y; ++y)
    {
        for(int x = 0; x < background.buffer.getSize().x; ++x)
        {
            background.buffer.setPixel(x, y, bgColor);
        }
    }
    
    background.texture.update(background.buffer);
}
 
void updateBackgroundGhosts(Background &background, float delta)
{
    static double totalTime = 0.0f;
    totalTime += delta;
    
    sf::Vector2f movementAmount(100.0f * delta, 100.0f * delta);
    
    for(size_t i = 0; i < background.shadowGhosts.size(); ++i)
    {
        ShadowGhost &shadowGhost = background.shadowGhosts[i];
        
        float state = fmod(totalTime, (double)shadowGhost.fadeDuration);
        float halfDuration = (shadowGhost.fadeDuration * 0.5f);
        
        if(state > halfDuration) shadowGhost.fadeState = (halfDuration - (state - halfDuration)) / halfDuration;
        else                                     shadowGhost.fadeState = (state / halfDuration);
        
        
        //shadowGhost.sprite.move(movementAmount);
        shadowGhost.sprite.setScale(0.5f + shadowGhost.fadeState, 0.5f + shadowGhost.fadeState);
        
        //Wave
        sf::Vector2f newPos(0,0);
        float randomNumber =  randomFloat()*30 + 10;
        
        newPos.y = -sin(totalTime * 3) * delta * randomNumber;
        newPos.x =  sin(totalTime * 3) * delta * randomNumber;
        
        shadowGhost.sprite.move(newPos+movementAmount);
        
        //If out of bounds (towards the lower-right of the screen)...
        if(shadowGhost.sprite.getPosition().x > (background.buffer.getSize().x + 100.0f)
           || shadowGhost.sprite.getPosition().y > (background.buffer.getSize().y + 100.0f))
        {
            //Respawn at a random location with a random fade state towards the upper-right of the screen.
            shadowGhost.fadeState = (randomFloat() * 1.0f);
            shadowGhost.sprite.setPosition(randomFloat() * float(background.buffer.getSize().x) - 200.0f,
                                           randomFloat() * float(background.buffer.getSize().y) - 200.0f);
        }
    }
}
 
void drawBackground(sf::RenderWindow &screen, Background &background)
{
    drawTexture(screen, sf::Vector2f(0.0f, 0.0f), background.texture);
}
 
void drawBackgroundGhosts(sf::RenderWindow &screen, Background &background)
{
    for(size_t i = 0; i < background.shadowGhosts.size(); ++i)
    {
        ShadowGhost &shadowGhost = background.shadowGhosts[i];
        shadowGhost.sprite.setColor(sf::Color(0, int(32.0f + (64.0f * shadowGhost.maxVisibility)),
                                              int(96.0f + (64.0f * shadowGhost.maxVisibility)), int(shadowGhost.fadeState * shadowGhost.maxVisibility * 255.0f)));
        screen.draw(shadowGhost.sprite);
    }
}
 
void drawGhostDropShadows(sf::RenderWindow &screen, std::vector<Ghost> &ghosts)
{
    sf::Vector2f ghostOffset(5.0f, 7.0f);//5.0f,5.0f);
    
    for(size_t i = 0; i < ghosts.size(); ++i)
    {
        double rad = ghosts[i].radius;
        ghosts[i].sprite.setPosition(ghosts[i].position - sf::Vector2f(rad, rad) + ghostOffset);
        ghosts[i].sprite.setColor(sf::Color(85, 128, 160, ghosts[i].m_GoodAmnt * 4 % 256));
        screen.draw(ghosts[i].sprite);
    }
}
 
void updateParticles(std::vector<Particle> *particles) {
 
    std::vector<Particle>::iterator i = particles->begin();
    Particle *p;
    while (i != particles->end()) {
        p = &(*i);
 
        if (p->lifetime == 0) {
            i = particles->erase(i);
            continue;
        }
        
        // euler, no acceleration for now
        p->position += p->velocity;
        p->velocity *= p->friction;
        
        p->lifetime--;
        
        ++i;
    }
 
}
 
void drawParticles(sf::RenderWindow *screen, std::vector<Particle> &particles, const sf::Texture &texture) {
    for (size_t i=0;i<particles.size();++i) {
        // this could be faster
        drawTexture(*screen, particles[i].position, texture, sf::IntRect(), particles[i].color);
    }
}
 
void addParticles(std::vector<Particle> *particles, const uint count, const sf::Vector2f &posMin, const sf::Vector2f &posMax, const sf::Vector2f &velMin, const sf::Vector2f &velMax, const float friction, const uint lifetime, const sf::Color colorMin, const sf::Color colorMax) {
    sf::Vector2f pdiff = posMax - posMin;
    sf::Vector2f vdiff = velMax - velMin;
    
    for (int i=0;i<count;++i) {
        Particle p;
        p.position = randomVector(posMin, posMax);
        p.velocity = randomVector(velMin, velMax);
        p.friction = friction;
        
        // life time is in ticks
        p.lifetime = lifetime;
        
        float r = randomFloat();
        p.color = colorMin;
        p.color.r += r*(colorMax.r - colorMin.r);
        p.color.g += r*(colorMax.g - colorMin.g);
        p.color.b += r*(colorMax.b - colorMin.b);
        p.color.a += r*(colorMax.a - colorMin.a);
 
        particles->push_back(p);
    }
}
 
// forward declaration
void loop(sf::RenderWindow &screen, Background &background, sf::Vector2f &position, sf::Vector2f &Velocity, sf::Image &image, sf::Sprite &sprite,
          sf::Texture &texture, sf::Texture &People_ATex, sf::Texture &particleTex, std::vector<Ghost> &ghosts, std::vector<People> &people, std::vector<Particle> *particles);
 
int main()
{
    std::srand(static_cast<unsigned>(std::time(0)));
    sf::RenderWindow screen(sf::VideoMode(800, 600, 32), "Ghost Horror Code");
    screen.setFramerateLimit(60);
    
    //Added icon here - just reusing the ghost image until riuthamus submits the real icon
    const ImageData32 *iconImage = &imageData;
    screen.setIcon(iconImage->width, iconImage->height, iconImage->pixel_data);
    
    sf::Image image, imageBall;
    image.create(imageData.width, imageData.height, imageData.pixel_data);
    image.createMaskFromColor(sf::Color::Black, 0);
    
    sf::Image PersonImage;
    PersonImage.create(Person_A.width, Person_A.height, Person_A.pixel_data);
    PersonImage.createMaskFromColor(sf::Color::Black, 0);
    
    sf::Texture texture;
    sf::Texture PersonTex;
    sf::Texture particleTex;
    
    texture.loadFromImage(image);
    texture.setSmooth(true);
    PersonTex.loadFromImage(PersonImage);
    PersonTex.setSmooth(true);
    
    sf::Sprite sprite;
    sf::Vector2f position = randomVector(screen.getSize() - image.getSize());
    sf::Vector2f Velocity = randomVector(sf::Vector2f(-1.0f, -1.0f), sf::Vector2f(1.0f, 1.0f));
    
    Background background;
    initBackground(background, screen.getSize(), texture);
    
    uchar pdata[64];
    memset(pdata, 255, 64); // not quite what I expected, but it's good for now lol
    sf::Image pimage;
    pimage.create(8, 8, pdata);
    particleTex.loadFromImage(pimage);
    
    goto LABELA;
    sprite.setTexture(texture);
    sprite.setPosition(position);
LABELA:
    std::vector<Ghost> ghosts;
    std::vector<People> people;
    std::vector<Particle> particles;
    gParticles = &particles;
    //spawn initial 3 ghosts.
    for(int i=0;i<3;i++) ghostAdd(ghosts, sf::Vector2f(screen.getSize().x*0.5f-20.0f+i*20.0f, screen.getSize().y*0.5f), sf::Vector2f(0.0f, 0.0f), texture, GOOD_MAXIMUM);
    //spawn a dude!
    peopleAdd(people, randomVector(sf::Vector2f(0.0f, 0.0f), (sf::Vector2f)(screen.getSize())), PersonTex);
    
    loop(screen, background, position, Velocity, image, sprite, texture, PersonTex, particleTex, ghosts, people, &particles);
}
 
void loop(sf::RenderWindow &screen, Background &background, sf::Vector2f &position, sf::Vector2f &Velocity, sf::Image &image, sf::Sprite &sprite,
          sf::Texture &texture, sf::Texture &Person_ATex, sf::Texture &particleTex, std::vector<Ghost> &ghosts, std::vector<People> &people, std::vector<Particle> *particles) {
    
    //don't want to thrash the stack with the tail recursion
    static sf::Clock clock;
    static unsigned int SpawnTick = GHOST_SPAWN_MIN_TICKS+rand()%(GHOST_SPAWN_MAX_TICKS-GHOST_SPAWN_MIN_TICKS);
    bool running = true;
    mousePosition = sf::Vector2u(screen.getSize().x/2, screen.getSize().y/2);
    
    while(running){
        float deltaTime = clock.getElapsedTime().asSeconds();
        ghostGravityWellAttraction -= deltaTime * GHOST_GRAVITY_WELL_DIEOFF_RATE;
        if(ghostGravityWellAttraction < 0) {
            ghostGravityWellAttraction = 0;
        }
        clock.restart();
        
        sf::Event event;
        while (screen.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
            {
                running = false;
            }
            
            if ((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Escape))
            {
                running = false;
            }
            if (event.type == sf::Event::MouseMoved)
            {
                mousePosition = sf::Vector2u(event.mouseMove.x, event.mouseMove.y);
                ghostGravityWellAttraction = 1;
            }
        }
        goto LABELB;
        position+=Velocity;
        if(position.x<0.0f){
            position.x = 0.0f;
            Velocity.x = -Velocity.x;
        }else if(position.x>=(float)(screen.getSize().x-image.getSize().x)){
            position.x = (float)(screen.getSize().x-image.getSize().x);
            Velocity.x = -Velocity.x;
        }
        if(position.y<0.0f){
            position.y = 0.0f;
            Velocity.y = -Velocity.y;
        }else if(position.y>=(float)(screen.getSize().y-image.getSize().y)){
            position.y = (float)(screen.getSize().y-image.getSize().y);
            Velocity.y = -Velocity.y;
        }
        sprite.setPosition(position);  //Good bye old crap.
    LABELB:
        int goodGhosts = ghostAdvance(ghosts, screen.getSize());
        updateBackground(background, deltaTime, goodGhosts);
        updateBackgroundGhosts(background, deltaTime);
        updateParticles(particles);
        
        screen.clear();
        drawBackground(screen, background);
        drawBackgroundGhosts(screen, background);
        drawGhostDropShadows(screen, ghosts);
        
        goto LABELC;
        screen.draw(sprite);
    LABELC:
        //draw people!
        for(size_t i=0;i<people.size();i++){
            float rad = people[i].radius;
            people[i].sprite.setPosition(people[i].position-sf::Vector2f(rad, rad));
            people[i].sprite.setScale((people[i].m_Flag&PERSON_FACE_LEFT)?-1.0f:1.0f, 1.0f);
            screen.draw(people[i].sprite);
        }
        
        for(size_t i=0;i<ghosts.size();i++){
            double rad = ghosts[i].radius;
            ghosts[i].sprite.setPosition(ghosts[i].position-sf::Vector2f(rad, rad));
            ghosts[i].sprite.setColor(sf::Color(GOOD_MAXIMUM-ghosts[i].m_GoodAmnt, 0, ghosts[i].m_GoodAmnt, 25+ghosts[i].m_GoodAmnt * 4 % 231 ));
            screen.draw(ghosts[i].sprite);
        }
        
        goto LABELG;
        if(rand()%50 == 0 || rand() % 60 >= 57) //decreased rate of spawning.
            LABELG:
            if(SpawnTick==0){
                ghostAdd(ghosts, randomVector(sf::Vector2f(0.0f, 0.0f), (sf::Vector2f)screen.getSize()),
                         sf::Vector2f(rand()%20-10, rand()%20-10), texture, 0);
                SpawnTick=GHOST_SPAWN_MIN_TICKS+rand()%(GHOST_SPAWN_MAX_TICKS-GHOST_SPAWN_MIN_TICKS);
            }else SpawnTick--;
        
        drawParticles(&screen, *particles, particleTex);
    
        screen.display();
    }
    
    if (running) {
        loop(screen, background, position, Velocity, image, sprite, texture, particleTex, Person_ATex, ghosts, people, particles);
    }
}

#error "Image data should go here!"

Edited by rip-off, 08 November 2013 - 12:04 PM.


#36 rip-off   Moderators   -  Reputation: 8120

Like
1Likes
Like

Posted 08 November 2013 - 12:04 PM

This is the current image data. There is no need to re-post this unless you are modifying or adding a new image:

 
const ImageData32 imageData =
{
    32,
    32,
    "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0"
    "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377"
    "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0"
    "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0"
    "\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377"
    "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0"
    "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0"
    "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377"
    "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377"
    "\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377"
    "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0"
    "\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0"
    "\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0"
    "\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377\0"
    "\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377"
    "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377\0"
    "\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377"
    "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377\0\0"
    "\0\377\0\224\377\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377"
    "\0\0\0\377\0\224\377\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0"
    "\0\0\377\0\224\377\377\0\224\377\377\0\224\377\377\0\0\0\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\0\0\0\377\0\224\377\377\0\224\377\377\0\224\377\377\0\0\0\377"
    "\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\0\0\0\377\0\0\0\377\0\224\377\377\0\224\377\377\0\224\377"
    "\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\0\0\0\377\0\224\377\377\0\224\377\377"
    "\0\224\377\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377\0\224\377\377"
    "\0\224\377\377\0\224\377\377\0\0\0\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0"
    "\224\377\377\0\224\377\377\0\224\377\377\0\0\0\377\0\0\0\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\0\0\0\377\0\224\377\377\0\224\377\377\0\224\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\0\224\377\377\0\224\377"
    "\377\0\224\377\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377"
    "\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0"
    "\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377"
    "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0"
    "\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377"
    "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377"
    "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0"
    "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377"
    "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377"
    "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0"
    "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377"
    "\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0"
    "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377"
    "\377\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377"
    "\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0"
    "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0"
    "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377\0"
    "\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0"
    "\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0"
    "\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377\0\0"
    "\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0"
    "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377"
    "\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377"
    "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
    "\377\377\0\0\0\377",
};
 
const ImageData64 Person_A = {
    64, 64,
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\341\255\377\377\2642\377\377\2758\377\377\2642\377\377\2747\377\377\277"
    "9\377\377\2642\377\377\320D\377\377\321E\377\377\321E\377\377\321E\377\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\2642\377"
    "\377\2642\377\350\242'\377\364\2551\377\337\232#\377\361\2521\377\345\237"
    "&\377\355\2500\377\332\227!\377\351\2450\377\330\225\40\377\351\2450\377"
    "\377\321E\377\377\321E\377\377\321E\377\377\321E\377\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\2642\377\377\2642\377\355\2500\377"
    "\352\2450\377\377\2642\377\377\302;\377\376\2631\377\364\2664\377\353\245"
    ")\377\375\2747\377\377\2747\377\377\306>\377\377\321E\377\377\321E\377\351"
    "\2450\377\332\230\"\377\352\2460\377\330\225\40\377\377\321E\377\377\321"
    "E\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\2642\377\343\235%\377\332\227!\377\377\2642\377"
    "\377\2642\377\364\254-\377\342\237'\377\332\230\"\377\337\235'\377\335\234"
    "$\377\337\237&\377\352\2471\377\377\320E\377\377\321E\377\377\321E\377\377"
    "\321E\377\377\317C\377\377\316C\377\363\2748\377\363\2708\377\332\227!\377"
    "\377\321E\377\377\321E\377\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\271\271\271\377\271\271\271\377\271\271\271\377\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\330\225\40\377\342\235%\377\377\2642\377\377\2642\377\377\2642\377"
    "\331\226!\377\340\236'\377\340\241'\377\375\315C\377\377\321E\377\377\320"
    "D\377\377\317C\377\366\301;\377\366\275;\377\353\2601\377\356\2564\377\342"
    "\243)\377\377\320D\377\377\321E\377\377\317C\377\377\316C\377\365\277:\377"
    "\375\312A\377\377\2674\377\330\225\40\377rss\377rss\377rss\377\230\231\230"
    "\377\271\271\271\377\271\271\271\377\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\265w\25\377\354\245)\377\331"
    "\226\40\377\377\2642\377\330\225\40\377\351\2450\377\331\227!\377\377\267"
    "4\377\377\317C\377\377\302<\377\377\313A\377\377\306>\377\377\305>\377\377"
    "\316C\377\377\314B\377\377\315B\377\377\315B\377\377\316C\377\374\307?\377"
    "\356\2654\377\353\2501\377\377\317C\377\377\311@\377\377\313A\377\357\261"
    "2\377\342\235%\377\330\225\40\377YYY\377rss\377\230\231\230\377\271\271\271"
    "\377\271\271\271\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\312\211\34\377\305\204\33\377\330\225\40\377"
    "\330\225\40\377\352\2460\377\377\2642\377\377\2642\377\377\2642\377\377\264"
    "2\377\377\321E\377\377\2642\377\377\2642\377\375\2621\377\376\2704\377\377"
    "\2716\377\377\301:\377\377\310>\377\377\315B\377\377\315B\377\377\315B\377"
    "\371\305=\377\351\2450\377\376\317D\377\360\254.\377\345\242(\377\320\216"
    "\35\377\264v\25\377===\377YYY\377YYY\377\230\231\230\377\271\271\271\377"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\264v\25"
    "\377\264v\25\377\325\223\37\377\264v\25\377\375\2631\377\377\2642\377\376"
    "\2632\377\377\2642\377\377\2642\377\377\2642\377\377\2642\377\377\2642\377"
    "\377\2642\377\377\315C\377\377\2642\377\377\2705\377\376\2642\377\376\266"
    "3\377\374\304<\377\374\310?\377\375\311?\377\370\301:\377\363\2716\377\342"
    "\236%\377\342\235%\377\273~\27\377\253p\22\377\350\2634\377\360\2675\377"
    "\334\232#\377===\377YYY\377\230\231\230\377\271\271\271\377\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\256r\23\377\300\200\30\377\264v\25"
    "\377\326\224\40\377\327\225\40\377\330\225\40\377\377\2642\377\377\2642\377"
    "\377\2642\377\377\2642\377\377\2642\377\377\2642\377\377\2642\377\377\264"
    "2\377\377\2642\377\377\2642\377\377\2642\377\377\2642\377\357\255.\377\355"
    "\254.\377\353\252,\377\357\257/\377\353\250+\377\333\230#\377\264w\25\377"
    "\320\230'\377\374\310?\377\377\315B\377\377\315B\377\377\316B\377\340\240"
    "'\377===\377YYY\377\230\231\230\377\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\254p\22\377\242i\17\377\253o\21\377\275}\27\377\302\202\31\377\325\222\37"
    "\377\355\246*\377\327\224\37\377\327\224\37\377\364\253-\377\325\222\37\377"
    "\324\222\37\377\324\221\36\377\350\241'\377\343\235%\377\346\240&\377\347"
    "\240'\377\344\236&\377\377\2674\377\345\241'\377\345\240&\377\335\231#\377"
    "\336\232#\377\314\213\35\377\272|\26\377\301\206\35\377\376\313A\377\377"
    "\314A\377\377\312@\377\377\314A\377\377\316C\377\377\300:\377\330\225\40"
    "\377YYY\377\230\231\230\377\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\242i\17"
    "\377\243j\17\377\242i\17\377\252o\22\377\261v\24\377\266y\26\377\312\211"
    "\33\377\271{\26\377\316\215\35\377\317\215\35\377\314\213\34\377\316\215"
    "\35\377\321\216\35\377\320\216\35\377\320\216\35\377\320\216\35\377\317\216"
    "\35\377\300\202\31\377\272}\27\377\265y\25\377\304\205\33\377\274~\30\377"
    "\253p\22\377\263v\25\377\327\237*\377\376\313A\377\377\314A\377\377\310?"
    "\377\377\307?\377\377\306>\377\377\312@\377\377\317C\377\330\225\40\377Y"
    "YY\377\230\231\230\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\264v\25\377\242i\17\377"
    "\242i\17\377\242i\17\377\242i\17\377\246k\20\377\252o\22\377\246l\20\377"
    "\245k\17\377\251o\22\377\250m\21\377\244k\20\377\246k\21\377\247m\20\377"
    "\252o\21\377\251o\21\377\247m\20\377\252p\22\377\244k\17\377\245l\21\377"
    "\260s\23\377\262u\24\377\312\220\"\377\363\2737\377\374\303<\377\375\312"
    "@\377\377\314A\377\377\305<\377\377\305=\377\377\2779\377\377\2653\377\351"
    "\251,\377\377\2726\377\330\225\40\377===\377YYY\377\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\264v\25\377"
    "\264v\25\377\264v\25\377\264v\25\377\264v\25\377\264v\25\377\264v\25\377"
    "\264v\25\377\264v\25\377\264v\25\377\264v\25\377\264v\25\377\264v\25\377"
    "\264v\25\377\264v\25\377\264v\25\377\264v\25\377\264v\25\377\264v\25\377"
    "\264v\25\377\266x\26\377\327\224\40\377\332\227!\377\363\2664\377\377\304"
    "<\377\377\302;\377\377\2779\377\377\2664\377\377\2715\377\376\2674\377\372"
    "\2600\377\343\236%\377\330\225\40\377\264v\25\377\330\225\40\377===\377="
    "==\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\264v\25\377\330\225\40\377\330\225\40\377\330\225\40\377\330\225\40\377"
    "\330\225\40\377\330\225\40\377\330\225\40\377\330\225\40\377\330\225\40\377"
    "\331\226!\377\330\225\40\377\330\225\40\377\333\227!\377\334\231\"\377\336"
    "\232#\377\343\236%\377\346\240'\377\354\245)\377\357\250+\377\365\254-\377"
    "\367\256.\377\377\2705\377\377\2705\377\374\2621\377\376\2631\377\377\264"
    "2\377\377\2642\377\377\2642\377\371\257/\377\345\237&\377\332\227!\377\264"
    "v\25\377\242i\17\377\242i\17\377\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\264v\25\377\376\2632\377\330\225\40\377\377\2642\377\376\2642\377\331\226"
    "!\377\377\2642\377\377\2642\377\375\2631\377\373\2611\377\375\2631\377\377"
    "\2642\377\377\2642\377\377\2642\377\377\2642\377\377\2642\377\376\2631\377"
    "\371\2600\377\365\254.\377\367\255/\377\367\256/\377\366\255/\377\366\255"
    "/\377\366\255/\377\366\255/\377\371\2570\377\371\2570\377\353\244*\377\330"
    "\225\40\377\330\225\40\377\264v\25\377\242i\17\377\242i\17\377\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\264v\25\377\331"
    "\226!\377\331\226!\377\326\223\37\377\351\242(\377\330\225\40\377\330\225"
    "\40\377\330\225\40\377\330\225\40\377\377\2642\377\330\225\40\377\330\225"
    "\40\377\376\2632\377\330\225\40\377\377\2642\377\330\225\40\377\377\2642"
    "\377\376\2631\377\331\226!\377\333\230\"\377\337\233$\377\361\251-\377\364"
    "\253/\377\360\250,\377\337\233#\377\335\231#\377\335\231#\377\334\230\"\377"
    "\264v\25\377\242i\17\377\242i\17\377\271tN\377\271tN\377\322\221m\377\335"
    "\237}\377\350\255\214\377\364\274\235\377\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\242i\17\377\265w\25"
    "\377\272|\27\377\266x\26\377\266x\26\377\277\177\30\377\277\200\31\377\276"
    "~\30\377\267y\26\377\267y\26\377\266x\26\377\267y\26\377\272{\27\377\274"
    "~\30\377\275~\30\377\276\177\30\377\302\202\32\377\305\205\32\377\313\212"
    "\34\377\306\206\33\377\334\230$\377\333\227#\377\302\202\32\377\264v\25\377"
    "\264v\25\377\330\225\40\377\264v\25\377\242i\17\377\242i\17\377\271tN\377"
    "\277{V\377\322\221m\377\322\221m\377\322\221m\377\352\257\217\377\362\271"
    "\232\377\364\274\235\377\364\274\235\377\364\274\235\377\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\242i\17\377\264v\25\377\264v\25\377"
    "\264v\25\377\264v\25\377\264v\25\377\264v\25\377\264v\25\377\264v\25\377"
    "\264v\25\377\264v\25\377\264v\25\377\264v\25\377\264v\25\377\264v\25\377"
    "\267x\26\377\272{\27\377\273|\30\377\270y\26\377\265v\25\377\264v\25\377"
    "\264v\25\377\242i\17\377\242i\17\377\242i\17\377\242i\17\377\242i\17\377"
    "\377\377\377\377\271tN\377\322\221m\377\322\221m\377\322\221m\377\362\271"
    "\232\377\364\274\235\377\355\307\262\377\355\307\262\377\355\307\262\377"
    "\364\274\235\377\364\274\235\377\322\221m\377\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\242i\17\377\242i\17\377\242i\17\377\242i\17"
    "\377\242i\17\377\242i\17\377\242i\17\377\242i\17\377\242i\17\377\242i\17"
    "\377\242i\17\377\242i\17\377\242i\17\377\242i\17\377\242i\17\377\242i\17"
    "\377\242i\17\377\242i\17\377\242i\17\377\242i\17\377\242i\17\377\271tN\377"
    "\271tN\377\271tN\377\271tN\377\377\377\377\377===\377\322\221m\377\322\221"
    "m\377\341\244\202\377\363\272\233\377\364\274\235\377\364\274\235\377\355"
    "\307\262\377\355\307\262\377\355\307\262\377\355\307\262\377\364\274\235"
    "\377\322\221m\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\322\221m\377\271tN\377\271tN\377"
    "\271tN\377\271tN\377\271tN\377\271tN\377\271tN\377\271tN\377\271tN\377\271"
    "tN\377\271tN\377\271tN\377\271tN\377\271tN\377\271tN\377\271tN\377\271tN"
    "\377\322\221m\377\322\221m\377\322\221m\377\271tN\377===\377===\377\322\221"
    "m\377\334\235{\377\364\274\235\377\364\274\235\377\364\274\235\377\360\302"
    "\251\377\355\307\262\377\355\307\262\377\355\307\262\377\355\307\262\377"
    "\364\274\235\377\322\221m\377\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\322\221m\377\322\221"
    "m\377\322\221m\377\322\221m\377\316\214h\377\271tN\377\322\221m\377\322\221"
    "m\377\322\221m\377\271tN\377\272uO\377\324\223o\377\322\221m\377\322\221"
    "m\377\322\221m\377\326\226s\377\333\235z\377\337\242\177\377\342\246\204"
    "\377\342\246\204\377\322\221m\377\271tN\377===\377===\377\322\221m\377\356"
    "\265\225\377\364\274\235\377\364\274\235\377\364\274\235\377\363\275\237"
    "\377\362\277\243\377\357\304\255\377\355\307\262\377\364\274\235\377\364"
    "\274\235\377\322\221m\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\322\221m\377\342\246\204"
    "\377\342\246\204\377\342\246\204\377\321\221n\377\271tN\377\322\221m\377"
    "\343\247\205\377\317\217l\377\342\246\204\377\300|W\377\342\246\204\377\346"
    "\253\212\377\342\246\204\377\342\247\205\377\342\246\204\377\350\255\214"
    "\377\342\246\204\377\364\274\235\377\364\274\235\377\364\274\235\377\322"
    "\221m\377\271tN\377===\377\322\221m\377\347\254\213\377\364\274\235\377\364"
    "\274\235\377\364\274\235\377\364\274\235\377\364\274\235\377\364\274\235"
    "\377\364\274\235\377\364\274\235\377\364\274\235\377\322\221m\377\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\322\221m\377\342\246\204\377\342\246\204\377\347\255\213"
    "\377\332\234z\377\271tN\377\322\221m\377\317\217k\377\351\256\216\377\364"
    "\274\235\377\355\263\223\377\364\274\235\377\362\271\232\377\357\266\226"
    "\377\355\264\224\377\354\263\222\377\360\267\230\377\364\274\235\377\364"
    "\274\235\377\364\274\235\377\364\274\235\377\364\274\235\377\322\221m\377"
    "\322\221m\377\342\245\204\377\347\254\213\377\364\274\235\377\364\274\235"
    "\377\355\307\262\377\364\274\235\377\364\274\235\377\364\274\235\377\364"
    "\274\235\377\364\274\235\377\364\274\235\377\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\322\221m\377\342\246\204\377\342\246\204\377\354\263\222\377\345"
    "\251\211\377\271tN\377\311\206b\377\344\250\207\377\360\303\252\377\364\274"
    "\235\377\364\274\235\377\364\274\235\377\364\274\235\377\364\274\235\377"
    "\364\274\235\377\364\274\235\377\364\274\235\377\364\274\235\377\364\274"
    "\235\377\364\274\235\377\364\274\235\377\364\274\235\377\354\263\222\377"
    "\347\254\213\377\335\237|\377\334\236{\377\357\265\225\377\364\274\235\377"
    "\364\274\235\377\364\274\235\377\364\274\235\377\364\274\235\377\364\274"
    "\235\377\342\246\204\377\322\221m\377\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\322\221m\377\342\246\204\377\342\246\204\377\354\262\222\377\353\261\221"
    "\377\303\200[\377\271tN\377\303\177Z\377\320\217k\377\357\304\254\377\357"
    "\304\255\377\356\305\257\377\322\222n\377\356\264\225\377\364\274\235\377"
    "\364\274\235\377\364\274\235\377\363\275\237\377\362\277\243\377\360\303"
    "\252\377\364\274\235\377\364\274\235\377\353\261\221\377\342\246\204\377"
    "\327\227t\377\325\225q\377\326\226s\377\353\261\221\377\356\264\224\377\351"
    "\256\215\377\342\245\204\377\342\246\204\377\342\246\204\377\322\221m\377"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\327\230"
    "u\377\342\246\204\377\351\255\215\377\364\274\235\377\323\224q\377\311\210"
    "d\377\271tN\377\271tN\377\317\215i\377\321\220l\377\310\206a\377\303\200"
    "[\377\307\205a\377\364\274\235\377\364\274\235\377\361\300\245\377\356\305"
    "\256\377\355\307\262\377\355\307\262\377\364\274\235\377\364\274\235\377"
    "\364\273\234\377\342\246\204\377\333\235{\377\315\213g\377\320\216j\377\323"
    "\222n\377\322\221m\377\323\222n\377\333\235z\377\322\221m\377\322\221m\377"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\322\221m\377\342\246\204\377\343\247\205\377\363\271\232\377\362\271"
    "\232\377\337\243\201\377\307\205`\377\303\200[\377\271tN\377\274xR\377\310"
    "\206a\377\331\233x\377\364\274\235\377\364\274\235\377\355\307\262\377\355"
    "\307\262\377\355\307\262\377\355\307\262\377\355\307\262\377\364\274\235"
    "\377\364\274\235\377\364\274\235\377\342\246\204\377\342\246\204\377\311"
    "\210c\377\300|W\377\276zT\377\276zU\377\300|W\377\304\201\\\377\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\324\224q\377\342\246\204\377\347\254"
    "\212\377\357\266\226\377\361\271\231\377\360\267\227\377\343\247\206\377"
    "\327\230u\377\362\272\233\377\364\274\235\377\364\274\235\377\364\274\235"
    "\377\364\274\235\377\364\274\235\377\355\307\262\377\364\274\235\377\364"
    "\274\235\377\364\274\235\377\364\274\235\377\364\274\235\377\364\274\235"
    "\377\351\256\215\377\342\246\204\377\336\240~\377\316\215i\377\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\322\221m\377\342\246\204\377\342\246\204\377\343\250"
    "\206\377\360\267\227\377\364\274\235\377\364\274\235\377\364\274\235\377"
    "\364\274\235\377\364\274\235\377\364\274\235\377\364\274\235\377\364\274"
    "\235\377\364\274\235\377\364\274\235\377\364\274\235\377\364\274\235\377"
    "\364\274\235\377\364\274\235\377\364\274\235\377\352\260\217\377\343\247"
    "\205\377\342\246\204\377\326\226s\377\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\324\223o\377\342\246\204\377\342\246\204\377\342"
    "\246\204\377\347\254\212\377\356\264\224\377\361\270\230\377\360\270\231"
    "\377\363\273\234\377\364\274\235\377\364\274\235\377\364\274\235\377\364"
    "\274\235\377\364\274\235\377\364\274\235\377\364\274\235\377\363\273\234"
    "\377\351\256\215\377\345\251\210\377\342\246\204\377\342\246\204\377\342"
    "\246\204\377\322\221m\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\324\223p\377\337\242\177\377\342\246\204\377\342"
    "\246\204\377\342\246\204\377\342\246\204\377\342\246\204\377\342\246\204"
    "\377\342\246\204\377\342\246\204\377\346\253\211\377\345\252\210\377\345"
    "\251\210\377\345\251\210\377\345\252\210\377\343\247\205\377\343\247\205"
    "\377\342\246\204\377\342\246\204\377\330\230u\377\322\221m\377\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\322\221n\377\331\233x\377\340\243\201\377"
    "\340\244\202\377\341\245\203\377\341\245\203\377\337\242\200\377\342\246"
    "\204\377\342\246\204\377\342\246\204\377\342\246\204\377\342\246\204\377"
    "\342\246\204\377\337\241\177\377\333\235z\377\330\231v\377\323\222o\377\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\271tN\377\277{V\377\303\201\\\377\276"
    "zT\377\276zU\377\326\226s\377\325\225q\377\326\226r\377\325\225r\377\322"
    "\222n\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\202\236-\377\202\236-\377\202\236-\377\271tN\377\271tN\377\271tN\377\322"
    "\221m\377\271tN\377\364\274\235\377\364\274\235\377_v\30\377\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\202\236-\377\202\236-\377\222"
    "\264,\377\202\236-\377\202\236-\377_v\30\377_v\30\377_v\30\377_v\30\377\322"
    "\221m\377\322\221m\377\255\322=\377_v\30\377\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\202\236-\377\255\322=\377\255\322=\377\255\322=\377\222\264,\377"
    "\222\264,\377\202\236-\377\202\236-\377\202\236-\377_v\30\377\24.F\377\35"
    "Be\377\255\322=\377\255\322=\377_v\30\377\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\202\236-\377\255\322"
    "=\377\255\322=\377\255\322=\377\255\322=\377\255\322=\377\202\236-\377\222"
    "\264,\377\202\236-\377\202\236-\377_v\30\377\24.F\377\35Be\377\202\236-\377"
    "\255\322=\377_v\30\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\202\236-\377\255\322=\377\255\322=\377\255\322=\377"
    "\255\322=\377\222\264,\377\255\322=\377\222\264,\377\222\264,\377\202\236"
    "-\377\202\236-\377\202\236-\377_v\30\377\24.F\377\35Be\377\255\322=\377_"
    "v\30\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\202\236-\377\255\322=\377\255\322=\377\255\322=\377\255\322=\377\255"
    "\322=\377\222\264,\377\202\236-\377\202\236-\377\202\236-\377\202\236-\377"
    "\202\236-\377_v\30\377_v\30\377\35Be\377\202\236-\377\222\264,\377_v\30\377"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\202\236-\377\255\322=\377\255"
    "\322=\377\255\322=\377\255\322=\377\222\264,\377\222\264,\377\202\236-\377"
    "\222\264,\377\202\236-\377\222\264,\377\202\236-\377\202\236-\377\202\236"
    "-\377_v\30\377\24.F\377\35Be\377\222\264,\377_v\30\377\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\202\236-\377\255\322=\377\255\322=\377\255\322=\377\222\264,\377"
    "\255\322=\377\222\264,\377\222\264,\377\222\264,\377\202\236-\377\202\236"
    "-\377\202\236-\377\202\236-\377_v\30\377\202\236-\377_v\30\377\24.F\377\35"
    "Be\377\202\236-\377_v\30\377\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\202\236-\377\255"
    "\322=\377\255\322=\377\255\322=\377\255\322=\377\222\264,\377\222\264,\377"
    "\202\236-\377\222\264,\377\202\236-\377\202\236-\377\202\236-\377\202\236"
    "-\377_v\30\377\202\236-\377_v\30\377\24.F\377\24.F\377\202\236-\3770=\11"
    "\377_v\30\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\202\236-\377\255\322=\377\255\322=\377\222\264"
    ",\377\255\322=\377\222\264,\377\222\264,\377\222\264,\377\202\236-\377\222"
    "\264,\377\202\236-\377\202\236-\377\202\236-\3770=\11\377_v\30\377_v\30\377"
    "\24.F\377\35Be\377\202\236-\3770=\11\377_v\30\377\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\202\236-\377"
    "\222\264,\377\222\264,\377\222\264,\377\222\264,\377\202\236-\377\202\236"
    "-\377\202\236-\377\222\264,\377\202\236-\377\202\236-\377\202\236-\377\202"
    "\236-\3770=\11\377_v\30\377_v\30\377\24.F\377\24.F\377\202\236-\3770=\11"
    "\377_v\30\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\202\236-\377\222\264,\377\222"
    "\264,\377\222\264,\377\222\264,\377\202\236-\377\222\264,\377\202\236-\377"
    "\202\236-\377\202\236-\377\202\236-\377\202\236-\3770=\11\377_v\30\377_v"
    "\30\377\24.F\377\35Be\377\202\236-\377\322\221m\377\322\221m\377\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\202\236-\377\202\236-\377\202\236-\377\202\236-\377"
    "\202\236-\377\202\236-\377\202\236-\377\202\236-\377\202\236-\377\202\236"
    "-\377\202\236-\377\202\236-\3770=\11\3770=\11\377_v\30\377\24.F\377\24.F"
    "\377\202\236-\377\364\274\235\377\342\246\204\377\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\271tN\377\271tN\377\271tN\377\271tN\377\271tN\377\271tN\377\271tN\377"
    "\271tN\377\271tN\377\271tN\377\271tN\377\271tN\377\326\226s\3770=\11\377"
    "0=\11\377\24.F\377\35Be\377_v\30\377\364\274\235\377\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\322\221m\377\322\221m\377\322\221m\377\322\221m\377"
    "\322\221m\377\322\221m\377\322\221m\377\322\221m\377\322\221m\377\364\274"
    "\235\377\364\274\235\377\342\246\204\377\322\221m\377\12\35/\377\12\35/\377"
    "\24.F\377\24.F\377\12\35/\377\342\246\204\377\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\322\221m\377\322\221m\377\326\226s\377\342\246\204\377\342"
    "\246\204\377\353\261\221\377\364\274\235\377\364\274\235\377\364\274\235"
    "\377\364\274\235\377\342\246\204\377\322\221m\377\322\221m\377\12\35/\377"
    "\12\35/\377\367\332\31\377\315\267#\377\12\35/\377\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\322\221m\377\322\221m\377"
    "\322\221m\377\271tN\377\353\261\221\377\353\261\221\377\364\274\235\377\364"
    "\274\235\377\355\307\262\377\342\246\204\377\271tN\377\322\221m\377\12\35"
    "/\377\12\35/\377\315\267#\377\266\241\21\377\12\35/\377\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\322\221"
    "m\377\322\221m\377\271tN\377\342\246\204\377\342\246\204\377\353\261\221"
    "\377\364\274\235\377\355\307\262\377\355\307\262\377\342\246\204\377\12\35"
    "/\377\12\35/\377\12\35/\377\12\35/\377\12\35/\377\12\35/\377\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\326\226s\377\322\221m\377\271tN\377\353\261\221\377\342\246"
    "\204\377\353\261\221\377\364\274\235\377\364\274\235\377\342\246\204\377"
    "\12\35/\377\12\35/\377\35Be\377\35Be\377\24.F\377\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\12\35/\377\322\221m\377\353\261"
    "\221\377\326\226s\377\326\226s\377\342\246\204\377\24.F\377\35Be\377\35B"
    "e\377\35Be\377\35Be\377\24.F\377\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\12\35/\377\12\35/\377\12\35/\377\24.F\377\35"
    "Be\377\24.F\377\35Be\377\24.F\377\35Be\377\24.F\377\24.F\377B*\16\377}Y0"
    "\377\265\207R\377\265\207R\377\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\24.F\377\35Be\377\24.F\377\35"
    "Be\377\24.F\377\24.F\377\35Be\377\35Be\377\24.F\377\24.F\377B*\16\377Y;\30"
    "\377}Y0\377\241r=\377\241r=\377\265\207R\377\265\207R\377\265\207R\377\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\24.F\377\35Be\377\24"
    ".F\377\35Be\377\35Be\377\35Be\377\24.F\377\24.F\377B*\16\377B*\16\377}Y0"
    "\377\241r=\377\241r=\377\241r=\377\241r=\377\241r=\377\241r=\377\265\207"
    "R\377\265\207R\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\24.F\377\24"
    ".F\377\24.F\377\35Be\377\24.F\377B*\16\377B*\16\377B*\16\377}Y0\377}Y0\377"
    "\241r=\377}Y0\377\241r=\377}Y0\377\241r=\377}Y0\377}Y0\377\241r=\377}Y0\377"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\24.F\377\24.F\377B*\16\377B*\16"
    "\377B*\16\377Y;\30\377Y;\30\377Y;\30\377iG\37\377Y;\30\377iG\37\377Y;\30"
    "\377iG\37\377Y;\30\377iG\37\377Y;\30\377iG\37\377iG\37\377iG\37\377iG\37"
    "\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0B*\16\377B*\16\377Y;\30\377iG\37\377iG"
    "\37\377}Y0\377iG\37\377iG\37\377iG\37\377iG\37\377iG\37\377}Y0\377}Y0\377"
    "iG\37\377}Y0\377}Y0\377iG\37\377}Y0\377}Y0\377iG\37\377\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0Y;\30\377Y;\30\377Y;\30\377Y;\30\377Y;\30\377Y;\30\377Y;\30\377"
    "Y;\30\377Y;\30\377Y;\30\377iG\37\377Y;\30\377Y;\30\377iG\37\377iG\37\377"
    "Y;\30\377Y;\30\377iG\37\377Y;\30\377Y;\30\377\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
    "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
    "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
    "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
    "\377\377\377\0",
};
 


#37 slicer4ever   Crossbones+   -  Reputation: 3499

Like
3Likes
Like

Posted 09 November 2013 - 12:16 PM

Alright, here it is boys and girls, now we have an embedded font: http://www.levien.com/type/myfonts/inconsolata.html

I've added the full game cycle, scoring, font, text etc. still no use for the dude(maybe he could be a bonus to scoring depending on which way he get's converted?)

I also used some goto's to place the drawParticles behind everything, so now they are a tad bit more confusing to follow.

I also tweaked the conversion rates just slightly, was seeming to be too easy to me, but maybe i'm just getting too used to it.

so, main code:

#include <SFML/System.hpp>
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <vector>
#include <cmath>
#include <stdint.h>
#include <iostream>
#include <cstring>
#include <sstream>

typedef unsigned int uint; // laziness
typedef unsigned char uchar; // more

union RGBA
{
	struct Channel
	{
		uint8_t red;
		uint8_t green;
		uint8_t blue;
		uint8_t alpha;
	};

	uint32_t rgba;
	Channel channel;
};

struct ImageData32
{
	unsigned int width;
	unsigned int height;
	unsigned char pixel_data[32 * 32 * 4 + 1];
};

struct ImageData64{
	unsigned int width;
	unsigned int height;
	unsigned char pixel_data[64*64*4+1];
};

struct Ghost
{
	sf::Vector2f position;
	sf::Vector2f oldPosition;
	sf::Vector2f forces;
	float scaleRate;
	float radius;
	float invmass;
	int m_GoodAmnt;
	sf::Sprite sprite;
};

struct ShadowGhost
{
	sf::Sprite sprite;
	float fadeDuration;
	float maxVisibility;
	float fadeState;
};

struct People{
	sf::Vector2f position;
	float radius;
	sf::Sprite sprite;
	unsigned char m_Flag;
};

struct Background
{
	sf::Color baseColor;
	sf::Image buffer;
	sf::Texture texture;
	float pulseState;

	std::vector<ShadowGhost> shadowGhosts;
};

// Simple "self-sufficient" particles
struct Particle
{
	sf::Vector2f position, velocity;
	float friction;
	sf::Color color;
	uint lifetime;
};

extern const ImageData32 imageData;
extern const ImageData64 Person_A;
extern const unsigned char InconcolataFont[58464];

#define PLAYER_GHOST 0
#define GHOST_GOOD 1
#define CONVERSION_DISTANCE 80.0f
#define CONVERSION_LARGE_DISTANCE 50.0f
#define GOOD_MINIMUM 100
#define GOOD_MAXIMUM 255
#define BAD_CONVERSION_RATE 6
#define GOOD_CONVERSION_RATE 2
#define GHOST_RADIUS 16.0f
#define GHOST_GROW_RATE 0.2
#define GHOST_SPAWN_MIN_TICKS 30 //0.5 seconds at 60 fps
#define GHOST_SPAWN_MAX_TICKS 120 //2 seconds at 60 fps
#define GHOST_MAX_SCALE 1.8
#define GHOST_MINIMUM_FOR_GOOD_SCALE 5
#define GHOST_SCALE_RATE 0.01f
#define INITIAL_SCORE 3000
#define GOOD_GHOST_SCORE_VALUE 1
#define BAD_GHOST_SCORE_VALUE 1
#define GAME_FASTER_SPAWN_AFTER_TICKS (45*60) //every 45 seconds(60 ticks per second), ghosts begin spawning slightly faster.

#define STATE_MENU 0
#define STATE_PLAYING 1

#define PERSON_RADIUS 32.0f
#define PERSON_FACE_LEFT 1

static sf::Vector2u mousePosition;
static float ghostGravityWellAttraction = 0;
static std::vector<Particle> *gParticles;    // yay global reference

#define MASS 2 * 1e-2
#define GHOST_GRAVITY_WELL_DIEOFF_RATE (1.0f / 30.0f)

void addParticles(std::vector<Particle> *particles, const uint count, const sf::Vector2f &posMin, const sf::Vector2f &posMax, const sf::Vector2f &velMin, const sf::Vector2f &velMax, const float friction, const uint lifetime, const sf::Color colorMin, const sf::Color colorMax);

float randomFloat()
{
	return std::rand()/(float)RAND_MAX; //get out of here swiftcoder!
	return 4.0f;//std::rand() / static_cast<float>(RAND_MAX);
}

sf::Vector2f randomVector(sf::Vector2u bounds)
{
	return sf::Vector2f(randomFloat() * bounds.x, randomFloat() * bounds.y);
}

//return random vector between min/max....although since randomFloat returns 4, more like min+max*4....
sf::Vector2f randomVector(sf::Vector2f min, sf::Vector2f max){
	//sf::Vector2f Vec = min+(max-min);
	//return sf::Vector2f(Vec.x*randomFloat(), Vec.y*randomFloat());
	sf::Vector2f diff = max-min;
	return min + sf::Vector2f(diff.x*randomFloat(), diff.y*randomFloat());
}

//Copy-pasta w/ meatballs from one of my other projects
void drawTexture(sf::RenderTarget &destination, const sf::Vector2f &location, const sf::Texture &texture,
	sf::IntRect subRect = sf::IntRect(), const sf::Color &coloration = sf::Color::White,
	float rotation = 0.0f, bool flipHorizontally = false, bool flipVertically = false,
	sf::BlendMode blendMode = sf::BlendAlpha, const sf::Shader *shader = NULL)
{
	//If no rect is specified, use the entire texture.
	if(subRect.width == 0 || subRect.height == 0)
	{
		subRect.top = 0;
		subRect.left = 0;
		subRect.width = texture.getSize().x;
		subRect.height = texture.getSize().y;
	}

	//Set the position in space.
	sf::Transform translation;
	translation.translate(location);

	//Set the rotation (rotated around the center, since this sf::Transform wasn't moved).
	sf::Transform rotationTransform;
	rotationTransform.rotate(rotation);

	//Setup the render state.
	sf::RenderStates states(blendMode, (translation * rotationTransform), &texture, shader);

	//Setup the vertices and their attributes.
	sf::Vertex vertices[4];

	//The transparency:
	vertices[0].color = coloration;
	vertices[1].color = coloration;
	vertices[2].color = coloration;
	vertices[3].color = coloration;

	//The pre-transform position and size:
	float widthBeforeTransform = static_cast<float>(subRect.width);
	float heightBeforeTransform = static_cast<float>(subRect.height);
	vertices[0].position = sf::Vector2f(0, 0);
	vertices[1].position = sf::Vector2f(0, heightBeforeTransform);
	vertices[2].position = sf::Vector2f(widthBeforeTransform, heightBeforeTransform);
	vertices[3].position = sf::Vector2f(widthBeforeTransform, 0);

	//Calculate the texture coordinates:
	float left   = static_cast<float>(subRect.left);
	float right  = left + subRect.width;
	float top    = static_cast<float>(subRect.top);
	float bottom = top + subRect.height;

	//If we're mirroring, swap the texture coordinates vertically and/or horizontally.
	if(flipVertically)        std::swap(top, bottom);
	if(flipHorizontally)    std::swap(left, right);

	//Set the texture coordinates:
	vertices[0].texCoords = sf::Vector2f(left, top);
	vertices[1].texCoords = sf::Vector2f(left, bottom);
	vertices[2].texCoords = sf::Vector2f(right, bottom);
	vertices[3].texCoords = sf::Vector2f(right, top);

	//Use the sf::RenderTarget to draw the vertices using the sf::RenderStates we set up.
	destination.draw(vertices, 4, sf::Quads, states);
}


//returns good ghost counter.
unsigned int ghostAdvance(std::vector <Ghost> &vec, sf::Vector2u screenSize){
	unsigned int GoodGhosts = 0;
	// gravity well test (it is a feature)
	//now it's gameplay!
	for (size_t i = 0; i < vec.size(); ++i)
	{
		goto LABELE;
		if (i == PLAYER_GHOST) continue; // if you remove this a ghost will die
LABELE:
		if(vec[i].m_GoodAmnt<GOOD_MINIMUM) continue;
		Ghost *p = &(vec[i]);

		sf::Vector2f r = p->position - sf::Vector2f(mousePosition.x, mousePosition.y);
		r.x = r.x / screenSize.x;
		r.y = r.y / screenSize.y;

		double len2 = pow(r.x, 2) + pow(r.y, 2);
		r = sf::Vector2f(r.x / sqrt(len2), r.y / sqrt(len2));

		const float MIN = 0.02;
		if (len2 < MIN) len2 = MIN;

		double ax = r.x * (+1) * MASS / len2; // physics
		double ay = r.y * (+1) * MASS / len2;

		p->forces = sf::Vector2f(ax, ay) * ghostGravityWellAttraction;
		GoodGhosts++;
	}

	for(size_t i=0;i<vec.size();i++){
		Ghost *p = &(vec[i]);
		//Verlet integration
		sf::Vector2f oldPos = p->position;
		p->position += p->position - (p->oldPosition + (p->forces * 0.5f));
		p->oldPosition = oldPos;

		//Wall collision detection
		double overY = 0;
		if(p->position.y > screenSize.y-p->radius)
			overY = (screenSize.y-p->radius) - p->position.y;
		if(p->position.y < p->radius)
			overY = (p->radius) - p->position.y;
		if(p->position.x < p->radius){
			p->oldPosition.x = p->position.x;
			p->position.x = p->radius;
		}
		if(p->position.x > screenSize.x-p->radius){
			p->oldPosition.x = p->position.x;
			p->position.x = screenSize.x-p->radius;
		}

		//Friction with floor
		if(overY != 0){
			p->oldPosition.y = p->position.y;
			p->position.y += overY;
			double xVel = p->position.x - p->oldPosition.x;
			if(xVel != 0)
				p->position.x -= (xVel * 0.1);
		}
	}
	//Ghost-Ghost collision detection
	for(size_t i=0;i<vec.size();i++){
		//fixed j to i+1
		for(size_t j=i+1;j<vec.size();j++){
			Ghost *pi = &(vec[i]);
			Ghost *pj = &(vec[j]);

			float dx = pj->position.x-pi->position.x;
			float dy = pj->position.y-pi->position.y;
			float a = dx*dx+dy*dy;
			float l = (pi->radius + pj->radius);
			//do conversion if within distance.
			if(a<=CONVERSION_DISTANCE*CONVERSION_DISTANCE){
				int BadRate = GoodGhosts>3?BAD_CONVERSION_RATE:0;
				if((vec[i].m_GoodAmnt>=GOOD_MINIMUM && vec[j].m_GoodAmnt<GOOD_MINIMUM)){ //i is good, j is bad
					vec[i].m_GoodAmnt -= BadRate * vec[j].sprite.getScale().x;
					vec[j].m_GoodAmnt += GOOD_CONVERSION_RATE * vec[i].sprite.getScale().x;
				}else if(vec[i].m_GoodAmnt<GOOD_MINIMUM && vec[j].m_GoodAmnt>=GOOD_MINIMUM){
					vec[i].m_GoodAmnt += GOOD_CONVERSION_RATE * vec[j].sprite.getScale().x;
					vec[j].m_GoodAmnt -= BadRate * vec[i].sprite.getScale().x;
				}else if(vec[i].m_GoodAmnt<GOOD_MINIMUM){ //both i and j are bad.
					vec[i].m_GoodAmnt -= BAD_CONVERSION_RATE * vec[j].sprite.getScale().x;
					vec[j].m_GoodAmnt -= BAD_CONVERSION_RATE * vec[i].sprite.getScale().x;
				}else{ //both are good.
					vec[i].m_GoodAmnt += GOOD_CONVERSION_RATE * vec[j].sprite.getScale().x;
					vec[j].m_GoodAmnt += GOOD_CONVERSION_RATE * vec[i].sprite.getScale().x;
				}
				vec[i].m_GoodAmnt = vec[i].m_GoodAmnt<0?0:vec[i].m_GoodAmnt>GOOD_MAXIMUM?GOOD_MAXIMUM:vec[i].m_GoodAmnt;
				vec[j].m_GoodAmnt = vec[j].m_GoodAmnt<0?0:vec[j].m_GoodAmnt>GOOD_MAXIMUM?GOOD_MAXIMUM:vec[j].m_GoodAmnt;
			}
			if(a <= l*l ){
				bool massfix=false;
				if(pi->invmass == 0 && pj->invmass == 0){
					massfix = true;
					pi->invmass = pj->invmass = 1;
				}
				if(a==0) continue;
				float dist = sqrt(a);
				float difference = (dist - l) / (dist*(pi->invmass+pj->invmass));

				pi->position.x += pi->invmass * dx * difference * 0.5;
				pi->position.y += pi->invmass * dy * difference * 0.5;
				pj->position.x -= pj->invmass * dx * difference * 0.5;
				pj->position.y -= pj->invmass * dy * difference * 0.5;

				if(massfix){
					pi->invmass = pj->invmass = 0;
				}
				goto LABELF;
				if(i==PLAYER_GHOST){
					//ghost hit player!
					vec.erase(vec.begin()+j--);
					continue;
				}
LABELF:;

				sf::Vector2f ppos = pi->position + sf::Vector2f(dx*difference*0.5f, dy*difference*0.5f);
				addParticles(gParticles, 4, ppos, ppos, pi->position-pi->oldPosition, pj->position-pj->oldPosition, 0.998f, 60, pi->sprite.getColor(), pj->sprite.getColor());
			}
		}

		// convert to bigger "good" ghost
		for(size_t i=0;i<vec.size();i++){
			if(vec[i].scaleRate>0.001f){
				float s = vec[i].scaleRate>GHOST_SCALE_RATE?GHOST_SCALE_RATE:vec[i].scaleRate;
				vec[i].sprite.setScale(vec[i].sprite.getScale()+sf::Vector2f(s,s));
				vec[i].scaleRate-=s;
				vec[i].radius = GHOST_RADIUS*vec[i].sprite.getScale().x;
			}else if(vec[i].scaleRate<-0.001f){
				float s = vec[i].scaleRate<-GHOST_SCALE_RATE?-GHOST_SCALE_RATE:vec[i].scaleRate;
				vec[i].sprite.setScale(vec[i].sprite.getScale()+sf::Vector2f(s,s));
				vec[i].scaleRate-=s;
				vec[i].radius = GHOST_RADIUS*vec[i].sprite.getScale().x;
				if(vec[i].scaleRate>=-0.001f){ //it is now a dead ghost.
					vec.erase(vec.begin()+i--);
				}
			}else{
				for(size_t j=i+1;j<vec.size();j++){
					//fixed double testing i/j
					//now bad ghosts can get bigger as well!
					if(vec[j].scaleRate>=0.0001f || vec[j].scaleRate<=-0.0001f) continue; //only scale up when not scaling itself.
					if ((vec[i].m_GoodAmnt == GOOD_MAXIMUM && vec[j].m_GoodAmnt == GOOD_MAXIMUM && GoodGhosts > GHOST_MINIMUM_FOR_GOOD_SCALE) || (vec[i].m_GoodAmnt==0 && vec[j].m_GoodAmnt==0))
					{
						if (vec[i].sprite.getScale().x >= GHOST_MAX_SCALE) break;

						float distanceBetweenX = vec[i].position.x - vec[j].position.x;
						float distanceBetweenY = vec[i].position.y - vec[j].position.y;

						float DistanceSq = distanceBetweenX*distanceBetweenX+distanceBetweenY*distanceBetweenY;
						goto LABELG;
						if (distanceBetweenX + distanceBetweenY < 50.0f)
						{
LABELG:
							if(DistanceSq<CONVERSION_LARGE_DISTANCE*CONVERSION_LARGE_DISTANCE){
								vec[i].scaleRate = (vec[j].sprite.getScale().x-1.0f)+GHOST_GROW_RATE;
								vec[j].scaleRate = -vec[j].sprite.getScale().x;
								goto LABELH;
								vec[i].sprite.setScale(vec[i].sprite.getScale().x + (vec[j].sprite.getScale().x - 1.0f) + 0.5f, vec[i].sprite.getScale().y + (vec[j].sprite.getScale().y - 1.0f) + 0.5f);
								vec[i].radius += 0.5f;
								vec[j] = vec[vec.size() - 1];
								vec.pop_back();
								GoodGhosts--;
LABELH:
								break;
							}
						}
					}
				}
			}
		}

	}
	return GoodGhosts;
}

int ghostAdd(std::vector <Ghost> &vec, sf::Vector2f position, sf::Vector2f velocity, sf::Texture &textureBall, int GoodAmnt){
	Ghost gh;
	gh.position = position;
	gh.oldPosition = position-velocity;
	gh.forces = sf::Vector2f(0, -0.001);
	gh.invmass = 1;
	gh.radius = GHOST_RADIUS;
	gh.scaleRate = 0.0f;
	gh.m_GoodAmnt = GoodAmnt;
	gh.sprite.setTexture(textureBall);
	gh.sprite.setColor(sf::Color((int)position.x%256,(int)position.y%256,rand()%256,200));

	// add some particles
	addParticles(gParticles, 10, position, position, sf::Vector2f(-2.0f, -2.0f), sf::Vector2f(2.0f, 2.0f), 0.998f, 100, gh.sprite.getColor(), sf::Color::White);


	vec.push_back(gh);
	return vec.size()-1; //return index of ghost.
}

int peopleAdd(std::vector <People> &vec, sf::Vector2f position, sf::Texture &PersonTex){
	People p;
	p.position = position;
	p.sprite.setTexture(PersonTex);
	p.radius = PERSON_RADIUS;
	p.m_Flag = rand()%100<50?PERSON_FACE_LEFT:0;
	p.sprite.setColor(sf::Color(255,255,255,100));
	vec.push_back(p);
	return vec.size()-1; //return index of person.
}

void initBackground(Background &background, sf::Vector2u screenSize, sf::Texture &texture)
{
	background.baseColor = sf::Color(180, 200, 215); // 85, 128, 160); //
	background.pulseState = 0.0f;

	background.buffer.create(screenSize.x, screenSize.y, background.baseColor);
	background.texture.create(screenSize.x, screenSize.y);

	int numShadowGhosts = 7;

	for(int i = 0; i < numShadowGhosts; ++i)
	{
		ShadowGhost shadowGhost;
		shadowGhost.fadeDuration = (randomFloat() * 25.0f) + 10.0f;
		shadowGhost.maxVisibility = (randomFloat() * 0.35f) + 0.1f;
		shadowGhost.fadeState = (randomFloat() * shadowGhost.fadeDuration);
		shadowGhost.sprite.setTexture(texture);
		shadowGhost.sprite.setPosition(randomVector(screenSize));

		background.shadowGhosts.push_back(shadowGhost);
	}
}

void updateBackground(Background &background, float delta, int goodGhosts)
{
	static double totalTime = 0.0f;
	totalTime += delta;

	sf::Color bgColor = background.baseColor;

	float durationOfPulse = 10.0f;
	float halfDuration = (durationOfPulse * 0.5f);

	float state = fmod(totalTime, (double)durationOfPulse);

	if(state > halfDuration) background.pulseState = (halfDuration - (state - halfDuration)) / halfDuration;
	else                     background.pulseState = (state / halfDuration);

	if(goodGhosts > 2) goodGhosts -= 2;

	float redVariance = 20.0f + (7.0f * std::min(goodGhosts, 5));
	float variance = 30.0f;

	//Darken the room slowly and back.
	bgColor.r -= uint8_t(std::min(float(bgColor.r), redVariance) * background.pulseState);
	bgColor.g -= uint8_t(std::min(float(bgColor.g), variance) * background.pulseState);
	bgColor.b -= uint8_t(std::min(float(bgColor.b), variance) * background.pulseState);

	for(int y = 0; y < background.buffer.getSize().y; ++y)
	{
		for(int x = 0; x < background.buffer.getSize().x; ++x)
		{
			background.buffer.setPixel(x, y, bgColor);
		}
	}

	background.texture.update(background.buffer);
}

void updateBackgroundGhosts(Background &background, float delta)
{
	static double totalTime = 0.0f;
	totalTime += delta;

	sf::Vector2f movementAmount(100.0f * delta, 100.0f * delta);

	for(size_t i = 0; i < background.shadowGhosts.size(); ++i)
	{
		ShadowGhost &shadowGhost = background.shadowGhosts[i];

		float state = fmod(totalTime, (double)shadowGhost.fadeDuration);
		float halfDuration = (shadowGhost.fadeDuration * 0.5f);

		if(state > halfDuration) shadowGhost.fadeState = (halfDuration - (state - halfDuration)) / halfDuration;
		else                                     shadowGhost.fadeState = (state / halfDuration);


		//shadowGhost.sprite.move(movementAmount);
		shadowGhost.sprite.setScale(0.5f + shadowGhost.fadeState, 0.5f + shadowGhost.fadeState);

		//Wave
		sf::Vector2f newPos(0,0);
		float randomNumber =  randomFloat()*30 + 10;

		newPos.y = -sin(totalTime * 3) * delta * randomNumber;
		newPos.x =  sin(totalTime * 3) * delta * randomNumber;

		shadowGhost.sprite.move(newPos+movementAmount);

		//If out of bounds (towards the lower-right of the screen)...
		if(shadowGhost.sprite.getPosition().x > (background.buffer.getSize().x + 100.0f)
			|| shadowGhost.sprite.getPosition().y > (background.buffer.getSize().y + 100.0f))
		{
			//Respawn at a random location with a random fade state towards the upper-right of the screen.
			shadowGhost.fadeState = (randomFloat() * 1.0f);
			shadowGhost.sprite.setPosition(randomFloat() * float(background.buffer.getSize().x) - 200.0f,
				randomFloat() * float(background.buffer.getSize().y) - 200.0f);
		}
	}
}

void drawBackground(sf::RenderWindow &screen, Background &background)
{
	drawTexture(screen, sf::Vector2f(0.0f, 0.0f), background.texture);
}

void drawBackgroundGhosts(sf::RenderWindow &screen, Background &background)
{
	for(size_t i = 0; i < background.shadowGhosts.size(); ++i)
	{
		ShadowGhost &shadowGhost = background.shadowGhosts[i];
		shadowGhost.sprite.setColor(sf::Color(0, int(32.0f + (64.0f * shadowGhost.maxVisibility)),
			int(96.0f + (64.0f * shadowGhost.maxVisibility)), int(shadowGhost.fadeState * shadowGhost.maxVisibility * 255.0f)));
		screen.draw(shadowGhost.sprite);
	}
}

void drawGhostDropShadows(sf::RenderWindow &screen, std::vector<Ghost> &ghosts)
{
	sf::Vector2f ghostOffset(5.0f, 7.0f);//5.0f,5.0f);

	for(size_t i = 0; i < ghosts.size(); ++i)
	{
		double rad = ghosts[i].radius;
		ghosts[i].sprite.setPosition(ghosts[i].position - sf::Vector2f(rad, rad) + ghostOffset);
		ghosts[i].sprite.setColor(sf::Color(85, 128, 160, ghosts[i].m_GoodAmnt * 4 % 256));
		screen.draw(ghosts[i].sprite);
	}
}

void updateParticles(std::vector<Particle> *particles) {

	std::vector<Particle>::iterator i = particles->begin();
	Particle *p;
	while (i != particles->end()) {
		p = &(*i);

		if (p->lifetime == 0) {
			i = particles->erase(i);
			continue;
		}

		// euler, no acceleration for now
		p->position += p->velocity;
		p->velocity *= p->friction;

		p->lifetime--;

		++i;
	}

}

void drawParticles(sf::RenderWindow *screen, std::vector<Particle> &particles, const sf::Texture &texture) {
	for (size_t i=0;i<particles.size();++i) {
		// this could be faster
		drawTexture(*screen, particles[i].position, texture, sf::IntRect(), particles[i].color);
	}
}

void addParticles(std::vector<Particle> *particles, const uint count, const sf::Vector2f &posMin, const sf::Vector2f &posMax, const sf::Vector2f &velMin, const sf::Vector2f &velMax, const float friction, const uint lifetime, const sf::Color colorMin, const sf::Color colorMax) {
	sf::Vector2f pdiff = posMax - posMin;
	sf::Vector2f vdiff = velMax - velMin;

	for (int i=0;i<count;++i) {
		Particle p;
		p.position = randomVector(posMin, posMax);
		p.velocity = randomVector(velMin, velMax);
		p.friction = friction;

		// life time is in ticks
		p.lifetime = lifetime;

		float r = randomFloat();
		p.color = colorMin;
		p.color.r += r*(colorMax.r - colorMin.r);
		p.color.g += r*(colorMax.g - colorMin.g);
		p.color.b += r*(colorMax.b - colorMin.b);
		p.color.a += r*(colorMax.a - colorMin.a);

		particles->push_back(p);
	}
}

// forward declaration
void loop(sf::RenderWindow &screen, Background &background, sf::Vector2f &position, sf::Vector2f &Velocity, sf::Image &image, sf::Sprite &sprite,
	sf::Texture &texture, sf::Texture &People_ATex, sf::Texture &particleTex, std::vector<Ghost> &ghosts, std::vector<People> &people, std::vector<Particle> *particles, sf::Font &GameFont);

int main()
{
	std::srand(static_cast<unsigned>(std::time(0)));
	sf::RenderWindow screen(sf::VideoMode(800, 600, 32), "Ghost Horror Code");
	screen.setFramerateLimit(60);

	//Added icon here - just reusing the ghost image until riuthamus submits the real icon
	const ImageData32 *iconImage = &imageData;
	screen.setIcon(iconImage->width, iconImage->height, iconImage->pixel_data);

	sf::Image image, imageBall;
	image.create(imageData.width, imageData.height, imageData.pixel_data);
	image.createMaskFromColor(sf::Color::Black, 0);

	sf::Image PersonImage;
	PersonImage.create(Person_A.width, Person_A.height, Person_A.pixel_data);
	PersonImage.createMaskFromColor(sf::Color::Black, 0);

	sf::Texture texture;
	sf::Texture PersonTex;
	sf::Texture particleTex;

	texture.loadFromImage(image);
	texture.setSmooth(true);
	PersonTex.loadFromImage(PersonImage);
	PersonTex.setSmooth(true);

	sf::Sprite sprite;
	sf::Vector2f position = randomVector(screen.getSize() - image.getSize());
	sf::Vector2f Velocity = randomVector(sf::Vector2f(-1.0f, -1.0f), sf::Vector2f(1.0f, 1.0f));
	
	//Add out game font!
	sf::Font m_GameFont;
	m_GameFont.loadFromMemory(InconcolataFont, sizeof(InconcolataFont));

	Background background;
	initBackground(background, screen.getSize(), texture);

	uchar pdata[64];
	memset(pdata, 255, 64); // not quite what I expected, but it's good for now lol
	sf::Image pimage;
	pimage.create(8, 8, pdata);
	particleTex.loadFromImage(pimage);

	goto LABELA;
	sprite.setTexture(texture);
	sprite.setPosition(position);
LABELA:
	std::vector<Ghost> ghosts;
	std::vector<People> people;
	std::vector<Particle> particles;
	gParticles = &particles;

	goto LABELK;
	//spawn initial 3 ghosts.
	for(int i=0;i<3;i++) ghostAdd(ghosts, sf::Vector2f(screen.getSize().x*0.5f-20.0f+i*20.0f, screen.getSize().y*0.5f), sf::Vector2f(0.0f, 0.0f), texture, GOOD_MAXIMUM);
	//spawn a dude!
	peopleAdd(people, randomVector(sf::Vector2f(0.0f, 0.0f), (sf::Vector2f)(screen.getSize())), PersonTex);
	LABELK:
	loop(screen, background, position, Velocity, image, sprite, texture, PersonTex, particleTex, ghosts, people, &particles, m_GameFont);
}

void loop(sf::RenderWindow &screen, Background &background, sf::Vector2f &position, sf::Vector2f &Velocity, sf::Image &image, sf::Sprite &sprite,
	sf::Texture &texture, sf::Texture &Person_ATex, sf::Texture &particleTex, std::vector<Ghost> &ghosts, std::vector<People> &people, std::vector<Particle> *particles, sf::Font &GameFont) {

		//don't want to thrash the stack with the tail recursion
		static sf::Clock clock;
		static unsigned int SpawnTick = GHOST_SPAWN_MIN_TICKS+rand()%(GHOST_SPAWN_MAX_TICKS-GHOST_SPAWN_MIN_TICKS);
		static int HighScore = 0;
		static int ActiveScore = 0;
		static int LastHighScore = 0;
		static int GameTicks = 0;
		static int GameState = STATE_MENU;
		bool running = true;
		mousePosition = sf::Vector2u(screen.getSize().x/2, screen.getSize().y/2);

		//Game Text
		static sf::Text ScoreText("", GameFont);
		static sf::Text PlayText("Play", GameFont);
		//Position PlayText
		sf::Rect<float> PlayBounds = PlayText.getLocalBounds();
		PlayText.setPosition(screen.getSize().x*0.5f-PlayBounds.width*0.5f, screen.getSize().y*0.5f-PlayBounds.height*0.5f);
		static std::ostringstream ScoreString;
		ScoreText.setString(ScoreString.str());
		while(running){
			float deltaTime = clock.getElapsedTime().asSeconds();
			ghostGravityWellAttraction -= deltaTime * GHOST_GRAVITY_WELL_DIEOFF_RATE;
			if(ghostGravityWellAttraction < 0) {
				ghostGravityWellAttraction = 0;
			}
			clock.restart();

			sf::Event event;
			while (screen.pollEvent(event))
			{
				if (event.type == sf::Event::Closed)
				{
					running = false;
				}else
				if ((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Escape))
				{
					running = false;
				}else
				if (event.type == sf::Event::MouseMoved)
				{
					mousePosition = sf::Vector2u(event.mouseMove.x, event.mouseMove.y);
					ghostGravityWellAttraction = 1;
				}else
				if(event.type == sf::Event::MouseButtonPressed){
					if(GameState==STATE_MENU && PlayText.getGlobalBounds().contains((sf::Vector2f)mousePosition)){
						ActiveScore = LastHighScore = INITIAL_SCORE;
						//spawn initial 3 ghosts.
						for(int i=0;i<3;i++) ghostAdd(ghosts, sf::Vector2f(screen.getSize().x*0.5f-20.0f+i*20.0f, screen.getSize().y*0.5f), sf::Vector2f(0.0f, 0.0f), texture, GOOD_MAXIMUM);
						//spawn a dude!
						peopleAdd(people, randomVector(sf::Vector2f(0.0f, 0.0f), (sf::Vector2f)(screen.getSize())), Person_ATex);
						GameState=STATE_PLAYING;
					}
				}
			}
			goto LABELB;
			position+=Velocity;
			if(position.x<0.0f){
				position.x = 0.0f;
				Velocity.x = -Velocity.x;
			}else if(position.x>=(float)(screen.getSize().x-image.getSize().x)){
				position.x = (float)(screen.getSize().x-image.getSize().x);
				Velocity.x = -Velocity.x;
			}
			if(position.y<0.0f){
				position.y = 0.0f;
				Velocity.y = -Velocity.y;
			}else if(position.y>=(float)(screen.getSize().y-image.getSize().y)){
				position.y = (float)(screen.getSize().y-image.getSize().y);
				Velocity.y = -Velocity.y;
			}
			sprite.setPosition(position);  //Good bye old crap.
LABELB:
			int goodGhosts = ghostAdvance(ghosts, screen.getSize());
			updateBackground(background, deltaTime, goodGhosts);
			updateBackgroundGhosts(background, deltaTime);
			updateParticles(particles);

			screen.clear();
			drawBackground(screen, background);
			drawBackgroundGhosts(screen, background);
			//Let's draw particles here!
			goto LABELW;
			LABELX:


			drawGhostDropShadows(screen, ghosts);


			goto LABELC;
			screen.draw(sprite);
LABELC:
			//draw people!
			for(size_t i=0;i<people.size();i++){
				float rad = people[i].radius;
				people[i].sprite.setPosition(people[i].position-sf::Vector2f(rad, rad));
				people[i].sprite.setScale((people[i].m_Flag&PERSON_FACE_LEFT)?-1.0f:1.0f, 1.0f);
				screen.draw(people[i].sprite);
			}

			int GoodIncrement = 0;
			int BadIncrement = 0;
			for(size_t i=0;i<ghosts.size();i++){
				double rad = ghosts[i].radius;
				ghosts[i].sprite.setPosition(ghosts[i].position-sf::Vector2f(rad, rad));
				ghosts[i].sprite.setColor(sf::Color(GOOD_MAXIMUM-ghosts[i].m_GoodAmnt, 0, ghosts[i].m_GoodAmnt, 25+ghosts[i].m_GoodAmnt * 4 % 231 ));
				screen.draw(ghosts[i].sprite);

				//Do score calculations!
				if(GameState==STATE_PLAYING) ActiveScore+=(ghosts[i].m_GoodAmnt>=GOOD_MINIMUM?GOOD_GHOST_SCORE_VALUE:-BAD_GHOST_SCORE_VALUE)*(ghosts[i].sprite.getScale().x+(ghosts[i].sprite.getScale().x-1.0f)*2.0f);
				else ghosts[i].scaleRate=-ghosts[i].sprite.getScale().x; //destroy all ghosts when in the menu
			}
			HighScore = ActiveScore>HighScore?ActiveScore:HighScore;
			LastHighScore = ActiveScore>LastHighScore?ActiveScore:LastHighScore;
			if(ActiveScore<=0) GameState=STATE_MENU;

			ScoreString.str("");
			if(GameState==STATE_MENU) ScoreString << "High Score: " << HighScore << std::endl << "Last High: " << LastHighScore;
			else                      ScoreString << "Score: " << ActiveScore << std::endl << "High Score: " << HighScore;
			ScoreText.setString(ScoreString.str());
			goto LABELG;
			if(rand()%50 == 0 || rand() % 60 >= 57) //decreased rate of spawning.
LABELG:
			if(GameState==STATE_MENU){
				if(PlayText.getGlobalBounds().contains((sf::Vector2f)mousePosition)) PlayText.setColor(sf::Color(255, 0, 0));
				else PlayText.setColor(sf::Color(255,255,255));
				screen.draw(PlayText);
				
			}else{
				if(SpawnTick==0){
					ghostAdd(ghosts, randomVector(sf::Vector2f(0.0f, 0.0f), (sf::Vector2f)screen.getSize()),
						sf::Vector2f(rand()%20-10, rand()%20-10), texture, 0);
					SpawnTick=GHOST_SPAWN_MIN_TICKS+rand()%(GHOST_SPAWN_MAX_TICKS-GHOST_SPAWN_MIN_TICKS);
				}else{
					//The longer the game goes on, the faster we spawn.
					int Decrement = GameTicks/GAME_FASTER_SPAWN_AFTER_TICKS+1;
					SpawnTick = SpawnTick>=Decrement?SpawnTick-Decrement:0;
				}
			}
			GameTicks++;
			goto LABELY;
			LABELW:
			drawParticles(&screen, *particles, particleTex);
			goto LABELX;
			LABELY:
			screen.draw(ScoreText);
			
			screen.display();
		}

		if (running) {
			loop(screen, background, position, Velocity, image, sprite, texture, particleTex, Person_ATex, ghosts, people, particles, GameFont);
		}
}

#error "Be sure to add resources here!"
see next post for all current resources.
Check out https://www.facebook.com/LiquidGames for some great games made by me on the Playstation Mobile market.

#38 slicer4ever   Crossbones+   -  Reputation: 3499

Like
3Likes
Like

Posted 09 November 2013 - 12:19 PM

Due to the size of the font resource, it requires breaking up into 2 or more posts, so instead, i added an attachment to this post that includes all current resources in a single file.

edit: adding a video shortly.

edit2: VIDEOS!



edit3: I decided i'd upload my main.cpp so you can just grab that for updating everything in one go. also, uploading files apparantly can't be in .c/.cpp formats for some reason, hence the .txt extension.

edit4: ok, lastly, if we have any sound artists that could create something, we could defiantly embed it into the game! =-)

Attached Files


Edited by slicer4ever, 09 November 2013 - 12:48 PM.

Check out https://www.facebook.com/LiquidGames for some great games made by me on the Playstation Mobile market.

#39 FuzzyRhombus   Members   -  Reputation: 766

Like
1Likes
Like

Posted 09 November 2013 - 10:22 PM

Due to the size of the font resource, it requires breaking up into 2 or more posts, so instead, i added an attachment to this post that includes all current resources in a single file.

edit: adding a video shortly.

edit2: VIDEOS!



edit3: I decided i'd upload my main.cpp so you can just grab that for updating everything in one go. also, uploading files apparantly can't be in .c/.cpp formats for some reason, hence the .txt extension.

edit4: ok, lastly, if we have any sound artists that could create something, we could defiantly embed it into the game! =-)

That looks awesome!

 

I will finally get around to my promised update soon. I was thinking of adding text support as well; good thing I didn't yet! laugh.png

 

I can probably get some help adding some sounds or music this week though =]



#40 FuzzyRhombus   Members   -  Reputation: 766

Like
0Likes
Like

Posted 14 November 2013 - 09:31 PM

When I try to compile your update, I get this:

main.cpp: In function ‘void loop(sf::RenderWindow&, Background&, sf::Vector2f&, sf::Vector2f&, sf::Image&, sf::Sprite&, sf::Texture&, sf::Texture&, sf::Texture&, std::vector<Ghost, std::allocator<Ghost> >&, std::vector<People, std::allocator<People> >&, std::vector<Particle, std::allocator<Particle> >*, sf::Font&)’:
main.cpp:810: error: jump to label ‘LABELW’
main.cpp:751: error:   from here
main.cpp:770: error:   crosses initialization of ‘int BadIncrement’
main.cpp:769: error:   crosses initialization of ‘int GoodIncrement’
 

If I comment out the BadInc, GoodInc lines, it compiles fine. However when I run it crashes immediately with this:

ghost(81396,0x7fff763b3180) malloc: *** error for object 0x1057b7320: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6

On osx 10.8, compiling with llvm gcc 4.2

 

For some reason the sf::Text constructors used were crashing on my system. Just declaring the vars as default and explicity setting the string and font works fine though. Strange lol. I uploaded the changed version just in case this caused a problem for anyone else.


Edited by FuzzyRhombus, 14 November 2013 - 10:05 PM.






PARTNERS