Advertisement
Aslai

Untitled

Aug 29th, 2013
136
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 54.87 KB | None | 0 0
  1. #ifdef __WIN32
  2. #include <SDL.h>
  3. #include <SDL_image.h>
  4. #undef main
  5. #else
  6. #include <SDL/SDL.h>
  7. #include <SDL/SDL_image.h>
  8. #undef main
  9. #endif
  10. #include <GL/gl.h>
  11. #include <GL/glu.h>
  12. #include<vector>
  13. #include<deque>
  14. #include<math.h>
  15. #include<string>
  16. #include<map>
  17. #include "luawrap.h"
  18. #include "fileio.h"
  19.  
  20. #include "soundloader.h"
  21. #include "audiomanager.h"
  22.  
  23. #define WIDTH 400
  24. #define HEIGHT 300
  25. #define SCALE 2
  26.  
  27. audiomanager* AudioMan;
  28.  
  29. int tileframe = 0;
  30.  
  31.  
  32. struct framelimiter{
  33.     Uint32 ticks;
  34.     Uint32 tickprev;
  35.  
  36.     int framerate;
  37.     int framecnt;
  38.  
  39.     /*int tracker[5000];
  40.     int trackerhead;
  41.     int trackertail;
  42.     int dur;
  43.  
  44.     int advance_val( int val ){
  45.         return (val + 1) % 5000;
  46.     }
  47.     int get_distance(){
  48.         if( trackerhead >= trackertail ) return trackerhead - trackertail;
  49.         return 5000 + trackerhead - trackertail;
  50.     }
  51.     int pop(){
  52.         int r = tracker[trackertail];
  53.         dur -= tracker[trackertail];
  54.         trackertail = advance_val( trackertail );
  55.         return r;
  56.     }
  57.     void push(int val){
  58.         dur += val;
  59.         tracker[trackerhead] = val;
  60.         trackerhead = advance_val( trackerhead );
  61.     }*/
  62.  
  63.     framelimiter( int fps ){
  64.         ticks = SDL_GetTicks();
  65.         tickprev = SDL_GetTicks();
  66.  
  67.         framerate = fps;
  68.         framecnt = 0;
  69.         //trackerhead = trackertail = 0;
  70.         //dur = 0;
  71.     }
  72.     void tick(){
  73.         framecnt ++;
  74.         Uint32 s = SDL_GetTicks();
  75.         int diff = s - tickprev;
  76.         //push(diff);
  77.         int tosleep = (framecnt * 1000 / framerate) - (s - ticks);
  78.  
  79.         //printf("%d\n", tosleep );
  80.         //while( dur > 2000 ){
  81.         //    ticks += pop();
  82.         //    framecnt--;
  83.         //}
  84.         if( framecnt > 10000000 ){
  85.             framecnt = 0;
  86.             ticks = SDL_GetTicks();
  87.         }
  88.  
  89.  
  90.         tickprev = s;
  91.         if( tosleep > 0 )
  92.         SDL_Delay( tosleep );
  93.     }
  94. };
  95.  
  96. class fatalerror{
  97.     std::string txt;
  98.     public:
  99.     fatalerror(std::string s){
  100.         txt = s;
  101.     }
  102.     const char* text(){
  103.         return txt.c_str();
  104.     }
  105. };
  106.  
  107. GLuint glLoadImageFile( const char* fname, int& width, int& height ){
  108.     SDL_Surface* surface = IMG_Load( fname );
  109.  
  110.     SDL_DisplayFormat( surface );
  111.     width = surface->w;
  112.     height = surface->h;
  113.  
  114.     GLuint texture;
  115.     glGenTextures( 1, &texture );
  116.     glBindTexture( GL_TEXTURE_2D, texture );
  117.  
  118.     gluBuild2DMipmaps( GL_TEXTURE_2D, 4, surface->w, surface->h, GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels );
  119.     SDL_FreeSurface( surface );
  120.  
  121.     return texture;
  122. }
  123.  
  124.  
  125.  
  126. struct image;
  127. struct image{
  128.     //static std::map<std::string, int> imagemap;
  129.     static std::vector<image> imagevector;
  130.     GLuint texture;
  131.     int texw, texh;
  132.     int xoffset, yoffset, xspace, yspace, tilewidth, tileheight;
  133.     std::string fname;
  134.     int id;
  135.     operator int(){ return id; }
  136.     static image& get( int name ){
  137.         return imagevector[external_to_local(name)];
  138.     }
  139.     static int local_to_external(int input){
  140.         return input + 1;
  141.     }
  142.     static int external_to_local(int input){
  143.         return input - 1;
  144.     }
  145.  
  146.     static int add( const char* fname, int w, int h, int xo, int yo, int xs, int ys ){
  147.         printf("Loading %s\n", fname );
  148.         image i;
  149.         i.texture = glLoadImageFile( fname, i.texw, i.texh );
  150.         i.xoffset = xo;
  151.         i.yoffset = yo;
  152.         i.xspace = xs;
  153.         i.yspace = ys;
  154.         i.tilewidth = w;
  155.         i.tileheight = h;
  156.         i.fname = fname;
  157.         i.id = local_to_external(imagevector.size());
  158.         imagevector.push_back( i );
  159.         return i.id;
  160.     }
  161.     void render( int collumn, int row, int xoff, int yoff ){
  162.         if(!glIsTexture( texture ) ){
  163.             texture = glLoadImageFile( fname.c_str(), texw, texh );
  164.         }
  165.         if(!glIsTexture( texture ) ){
  166.             throw(fatalerror("Failed to load "+fname));
  167.         }
  168.         glEnable(GL_TEXTURE_2D);
  169.         glBindTexture(GL_TEXTURE_2D,texture);
  170.  
  171.         glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
  172.         // when texture area is large, bilinear filter the original
  173.         glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
  174.  
  175.  
  176.         glBegin( GL_TRIANGLE_STRIP );
  177.         double xc = (xoffset + collumn * (xspace + tilewidth))/((double)texw);
  178.         double yc = (yoffset + row * (yspace + tileheight))/((double)texh);
  179.         double ww = tilewidth / ((double)texw);
  180.         double hh = tileheight / ((double)texh);
  181.  
  182.         glTexCoord2d( xc + ww, yc );        glVertex2d( xoff + tilewidth,   yoff );
  183.         glTexCoord2d( xc, yc );             glVertex2d( xoff,               yoff );
  184.         glTexCoord2d( xc + ww, yc + hh );   glVertex2d( xoff + tilewidth,   yoff + tileheight );
  185.         glTexCoord2d( xc, yc + hh );        glVertex2d( xoff,               yoff + tileheight );
  186.  
  187.         glEnd();
  188.         glDisable(GL_TEXTURE_2D);
  189.     }
  190. };
  191. //std::map<std::string, int> image::imagemap;
  192. std::vector<image> image::imagevector;
  193.  
  194. struct sprite{
  195.     static std::map<std::string, int> spritemap;
  196.     static std::vector<sprite> spritevector;
  197.     static int local_to_external(int input){
  198.         return input + 1;
  199.     }
  200.     static int external_to_local(int input){
  201.         return input - 1;
  202.     }
  203.     static sprite& get(std::string name){
  204.         int t = external_to_local(spritemap[name]);
  205.         //if( t < 0 ) throw(5);
  206.         return spritevector[t];
  207.     }
  208.     static sprite& get(int name){
  209.         return spritevector[external_to_local(name)];
  210.     }
  211.  
  212.  
  213.     std::string name;
  214.     int img, collumn, row, length, originx, originy;
  215.     int id;
  216.         operator int(){ return id; }
  217.     static int add(const char* name, int img, int x, int y, int l, int origx, int origy ){
  218.         printf("Loading %s\n", name );
  219.         sprite s;
  220.         s.name = name;
  221.         s.img = img;
  222.         s.collumn = x;
  223.         s.row = y;
  224.         s.length = l;
  225.         s.originx = origx;
  226.         s.originy = origy;
  227.         s.id = local_to_external(spritevector.size());
  228.         spritevector.push_back( s );
  229.         spritemap[name] = s.id;
  230.         return s.id;
  231.     }
  232.     void draw( int frame ){
  233.         image::get( img ).render( collumn + (frame % length), row, -originx, -originy );
  234.     }
  235. };
  236. std::map<std::string, int> sprite::spritemap;
  237. std::vector<sprite> sprite::spritevector;
  238.  
  239. struct tileset{
  240.     static std::map<std::string, int> tilesetmap;
  241.     static std::vector<tileset> tilesetvector;
  242.     static int local_to_external(int input){
  243.         return input + 1;
  244.     }
  245.     static int external_to_local(int input){
  246.         return input - 1;
  247.     }
  248.     static tileset& get(std::string name){
  249.         return tilesetvector[external_to_local(tilesetmap[name])];
  250.     }
  251.     static tileset& get(int name){
  252.         return tilesetvector[external_to_local(name)];
  253.     }
  254.  
  255.  
  256.     std::string name;
  257.     std::vector<int> sprites;
  258.     int id;
  259.         operator int(){ return id; }
  260.     static int add(const char* name, int sprit ){
  261.         printf("Loading %s\n", name );
  262.         tileset t;
  263.         t.name = name;
  264.         t.sprites.push_back( sprit );
  265.         t.id = local_to_external(tilesetvector.size());
  266.         tilesetvector.push_back( t );
  267.         tilesetmap[name] = t.id;
  268.         return t.id;
  269.     }
  270.     static int add_animation(const char* name){
  271.         printf("Loading %s\n", name );
  272.         tileset t;
  273.         t.name = name;
  274.         t.id = local_to_external(tilesetvector.size());
  275.         tilesetvector.push_back( t );
  276.         tilesetmap[name] = t.id;
  277.         return t.id;
  278.     }
  279.     static int add_animation_frame(int id, int sprit){
  280.         tilesetvector[external_to_local(id)].sprites.push_back(sprit);
  281.         return id;
  282.     }
  283.     static int add_animation_finish(int id){
  284.         return id;
  285.     }
  286.  
  287.     void draw( int frame, int type ){
  288.         sprite::get(sprites[frame % sprites.size()]).draw( type );
  289.     }
  290. };
  291. std::map<std::string, int> tileset::tilesetmap;
  292. std::vector<tileset> tileset::tilesetvector;
  293.  
  294.  
  295.  
  296. struct sound{
  297.     //decoder* d;
  298.     static std::map<std::string, int> soundmap;
  299.     static std::vector<sound> soundvector;
  300.     static int local_to_external(int input){
  301.         return input + 1;
  302.     }
  303.     static int external_to_local(int input){
  304.         return input - 1;
  305.     }
  306.     static sound& get(std::string name){
  307.         return soundvector[external_to_local(soundmap[name])];
  308.     }
  309.     static sound& get(int name){
  310.         return soundvector[external_to_local(name)];
  311.     }
  312.  
  313.     int id, loops, volume;
  314.     std::string fname;
  315.     std::string name;
  316.     int audio;
  317.  
  318.     operator int(){ return id; }
  319.     static int add(const char* fname, const char* name, int loops, int volume ){
  320.         printf("Loading %s\n", fname );
  321.         sound s;
  322.         s.loops = loops;
  323.         s.volume = volume;
  324.         s.fname = fname;
  325.         s.name = name;
  326.         s.audio = AudioMan->load( fname );
  327.         (*AudioMan)[s.audio]->loop(s.loops);
  328.  
  329.  
  330.         s.id = local_to_external(soundvector.size());
  331.         soundvector.push_back( s );
  332.         soundmap[name] = s.id;
  333.         return s.id;
  334.     }
  335.  
  336.     void play(){
  337.         (*AudioMan)[audio]->seek( SEEK_SET, 0 );
  338.         (*AudioMan)[audio]->play(true);
  339.     }
  340.     void stop(){
  341.         (*AudioMan)[audio]->play(false);
  342.     }
  343.     void setrip( double val ){
  344.         (*AudioMan)[audio]->setrip(val);
  345.     }
  346. };
  347. std::map<std::string, int> sound::soundmap;
  348. std::vector<sound> sound::soundvector;
  349.  
  350. struct level{
  351.     static std::map<std::string, int> levelmap;
  352.     static std::vector<level> levelvector;
  353.     static int local_to_external(int input){
  354.         return input + 1;
  355.     }
  356.     static int external_to_local(int input){
  357.         return input - 1;
  358.     }
  359.     static level& get(std::string name){
  360.         return levelvector[external_to_local(levelmap[name])];
  361.     }
  362.     static level& get(int name){
  363.         return levelvector[external_to_local(name)];
  364.     }
  365.     struct tile{
  366.         int idx;
  367.         int type;
  368.         int hazard;
  369.         tile(){
  370.             idx = -1;
  371.             type = -1;
  372.             hazard = false;
  373.         }
  374.     };
  375.     std::vector<tile> tiles;
  376.     int id, width, height;
  377.     std::string fname;
  378.     std::string name;
  379.  
  380.     operator int(){ return id; }
  381.  
  382.     void set_tile( int x, int y, tile t ){
  383.         tiles[x+y*width] = t;
  384.     }
  385.     tile& get_tile( int x, int y ){
  386.         return tiles[x+y*width];
  387.     }
  388.     struct object{
  389.         std::string type;
  390.         int x, y;
  391.     };
  392.     std::vector<object> objs;
  393.  
  394.     static int add_tile( level* self, int x, int y, const char* type, int idx, int hazard ){
  395.         //printf("Adding Tile: %d %d, %s, %d\n", x, y, type, idx);
  396.         tile t;
  397.         t.idx = idx;
  398.         t.type = tileset::get( type ).id;
  399.         t.hazard = hazard;
  400.         self->set_tile( x, y, t );
  401.         return 0;
  402.     }
  403.     static int add_object( level* self, const char* type, int x, int y ){
  404.         printf("Adding Object: %s, %d %d\n", type, x, y);
  405.         object o;
  406.         o.type = type;
  407.         o.x = x;
  408.         o.y = y;
  409.         self->objs.push_back( o );
  410.         return 0;
  411.     }
  412.     static int set_dimension( level* self, int x, int y){
  413.         printf("Setting Dimensions: %d %d\n", x, y);
  414.         self->width = x;
  415.         self->height = y;
  416.         self->tiles.clear();
  417.         self->tiles.resize( x * y );
  418.         return 0;
  419.     }
  420.  
  421.  
  422.     static int add(const char* fname, const char* name ){
  423.         printf("Loading %s\n", fname );
  424.         level l;
  425.         l.fname = fname;
  426.         l.name = name;
  427.  
  428.         l.id = local_to_external(levelvector.size());
  429.         levelvector.push_back( l );
  430.         levelmap[name] = l.id;
  431.  
  432.         std::string dumper ="\n\n\n\
  433. set_dimensions( self, width, height )\n\
  434. for i=1,#level do\n\
  435.     add_tile( self, level[i][1], level[i][2], level[i][3], level[i][4], level[i][5] )\n\
  436. end\n\
  437. for i=1,#objects do\n\
  438.     add_object( self, objects[i][1], objects[i][2], objects[i][3])\n\
  439. end\n";
  440.         std::string re = read_file_to_buffer( fname ).c_str()+dumper;
  441.         //printf("\n\n%s\n\n",re.c_str());
  442.         Lua L(re.c_str(), fname, 0);
  443.         L.set("self", &(levelvector[external_to_local(l.id)]));
  444.         L.funcreg<int, level*, int, int, const char*, int, int, add_tile>( "add_tile" );
  445.         L.funcreg<int, level*, const char*, int, int, add_object>( "add_object" );
  446.         L.funcreg<int, level*, int, int, set_dimension>( "set_dimensions" );
  447.  
  448.         L.run();
  449.  
  450.         return l.id;
  451.     }
  452.     void draw(){
  453.  
  454.         glColor3ub(255,255,255);
  455.         for( int i = 0; i < width; ++i ){
  456.             for( int j = 0; j < height; ++j ){
  457.                 if( get_tile( i, j ).type != -1 ){
  458.                     glPushMatrix();
  459.                     glTranslated( i * 16,j * 16, 0 );
  460.                     tileset::get(get_tile( i, j ).type).draw(tileframe, get_tile( i, j ).idx);
  461.                     glPopMatrix();
  462.                 }
  463.  
  464.             }
  465.  
  466.         }
  467.     }
  468.     void unload();
  469.     void load();
  470.  
  471. };
  472. std::map<std::string, int> level::levelmap;
  473. std::vector<level> level::levelvector;
  474.  
  475. level* levelloaded = 0;
  476.  
  477. class entity{
  478. public:
  479.     struct position{
  480.         double x, y;
  481.         double rotation;
  482.         double xscale;
  483.         double imageindex;
  484.         double imagespeed;
  485.         int spriteindex;
  486.         int visible;
  487.         position(){
  488.             x = y = rotation = xscale = imageindex = imagespeed = spriteindex = 0;
  489.             visible = 1;
  490.         }
  491.         //double timestamp;
  492.     };
  493.     class biezercurve{
  494.         std::vector<position> points;
  495.     public:
  496.         biezercurve( std::deque<position> p ){
  497.             while( p.size() > 0 ){
  498.                 points.push_back( p.back() );
  499.                 p.pop_back();
  500.             }
  501.         }
  502.         position get( double time ){
  503.             /*position p = {0};
  504.             if( points.size() == 0 ) return p;
  505.             if( points.size() == 1 ) return points[0];
  506.             std::deque<position> positions;
  507.             for( size_t i = 0; i < points.size() - 1; ++i ){
  508.                 p.x = points[i].x + ( points[i+1].x - points[i].x ) * time;
  509.                 p.y = points[i].y + ( points[i+1].y - points[i].y ) * time;
  510.                 p.rotation = points[i].rotation + ( points[i+1].rotation - points[i].rotation ) * time;
  511.                 p.xscale = points[i].xscale + ( points[i+1].xscale - points[i].xscale ) * time;
  512.                 p.imageindex = points[i].imageindex + ( points[i+1].imageindex - points[i].imageindex ) * time;
  513.                 int t = (int)(time*points.size());
  514.                 if( t >= points.size() ) t = points.size() - 1;
  515.                 if( t < 0 ) t = 0;
  516.                 if( time < 0 ) t = 0;
  517.                 p.spriteindex = points[t].spriteindex;
  518.                 positions.push_front( p );
  519.             }
  520.             if( positions.size() == 1 ) return positions.back();
  521.             biezercurve subbiezer(positions);
  522.             return subbiezer.get( time );*/
  523.             position p;
  524.             int i = (points.size()-1) * time;
  525.             int k = points.size();
  526.             if( i >= points.size()-1 || time >= 1 ) return points[points.size()-1];
  527.             if( i <= 0 ) return points[0];
  528.  
  529.             time = time / ( 1.0/(points.size()-1) );
  530.             time -= floor( time );
  531.             p.x = points[i].x + ( points[i+1].x - points[i].x ) * time;
  532.             p.y = points[i].y + ( points[i+1].y - points[i].y ) * time;
  533.             p.rotation = points[i].rotation + ( points[i+1].rotation - points[i].rotation ) * time;
  534.             p.xscale = points[i].xscale + ( points[i+1].xscale - points[i].xscale ) * time;
  535.             p.xscale = points[i].xscale;
  536.             p.imageindex = points[i].imageindex + ( points[i+1].imageindex - points[i].imageindex ) * time;
  537.             p.imagespeed = points[i].imagespeed + ( points[i+1].imagespeed - points[i].imagespeed ) * time;
  538.  
  539.             p.spriteindex = points[i].spriteindex;
  540.             p.visible = points[i].visible;
  541.  
  542.             return p;
  543.         }
  544.     };
  545. private:
  546.     //position location;
  547.     std::deque<position> history;
  548.     bool timeaffects;
  549. public:
  550.     //static std::map<std::string, int> entitymap;
  551.     //static std::vector<entity> entityvector;
  552.     double w, h;
  553.     int type;
  554.     double xspeed, yspeed;
  555.  
  556.  
  557.  
  558.     position location;
  559.     entity( position Location, bool affectedbytime = true ){
  560.         location = Location;
  561.         timeaffects = affectedbytime;
  562.     }
  563.     entity( double x, double y, double rotation = 0, bool affectedbytime = true ){
  564.         position p;
  565.         p.rotation = rotation;
  566.         p.x = x;
  567.         p.y = y;
  568.         p.xscale = 1;
  569.         p.imagespeed = 1;
  570.         p.visible = true;
  571.         location = p;
  572.  
  573.  
  574.         timeaffects = affectedbytime;
  575.         //printf("aa: %f\n\n", location.y);
  576.     }
  577.     void updatetime( double time ){
  578.         //location.timestamp = time;
  579.         if( timeaffects )
  580.             history.push_back( location );
  581.     }
  582.     void rewind( double amt ){
  583.         if( timeaffects )
  584.             {
  585.             biezercurve b( history );
  586.             location = b.get(amt);
  587.         }
  588.     }
  589.     void rewindclear(){
  590.         history.clear();
  591.     }
  592.     void draw(){
  593.         if( !location.visible) return;
  594.         glMatrixMode(GL_MODELVIEW);
  595.         //double d = sqrt( 50 );
  596.         //glColor3ub( rand()%256, rand()%256, rand()%256 );
  597.         ///////////////if( timeaffects )
  598.             glColor3ub(255,255,255);
  599.         //else
  600.             //glColor3ub(166,100,100);
  601.         glPushMatrix();
  602.        // glTranslated(1, 1, 0 );
  603.         glTranslated( location.x, location.y, 0 );
  604.  
  605.         glRotated( location.rotation, 0, 0, 1 );
  606.         glScaled( location.xscale, 1, 1 );
  607.         /*glBegin( GL_TRIANGLE_STRIP );
  608.         glVertex2d( 5, -5 );
  609.         glVertex2d( -5, -5 );
  610.         glVertex2d( 5, 5 );
  611.         glVertex2d( -5, 5 );
  612.         glEnd();*/
  613.  
  614.         sprite::get(location.spriteindex).draw(location.imageindex);
  615.         location.imageindex+= location.imagespeed;;
  616.         glPopMatrix();
  617.         //printf("%f, %f, %f\n", location.x, location.y, location.rotation);
  618.     }
  619.     virtual void onframe() = 0;
  620.     virtual void reset() = 0;
  621.     virtual void collide_left( entity* other, double sp ) = 0;
  622.     virtual void collide_right( entity* other, double sp ) = 0;
  623.     virtual void collide_top( entity* other, double sp ) = 0;
  624.     virtual void collide_bottom( entity* other, double sp ) = 0;
  625.  
  626.  
  627. };
  628.  
  629. //std::map<std::string, int> entity::entitymap;
  630. //std::vector<entity> entity::entityvector;
  631.  
  632. int print(const char* s, const char* o, int a, int b ){
  633. printf(s);
  634. return 1;
  635. }
  636. int print2(const char* s){
  637. printf(s);
  638. return 1;
  639. }
  640.  
  641. std::vector<entity*> entities;
  642.  
  643. struct trapdoor : entity{
  644.     bool opened;
  645.     std::string color;
  646.     trapdoor( int x, int y, std::string color ): entity( x, y, 0, true ){
  647.         opened = false;
  648.         location.spriteindex = sprite::get("trapdoor_" + color);
  649.         trapdoor::color = color;
  650.         w = 16;
  651.         h = 2;
  652.         location.imagespeed = 0;
  653.         location.imageindex = 0;
  654.  
  655.         entities.push_back( this );
  656.         type = 3;
  657.     }
  658.     void collide_left(entity* other, double speed){
  659.         /*if( !opened ){
  660.             other->xspeed = 0;
  661.             other->location.x = location.x - w - other->w;
  662.         }*/
  663.     }
  664.     void collide_right(entity* other, double speed){
  665.         /*if( !opened ){
  666.             other->xspeed = 0;
  667.             other->location.x = location.x + w + other->w;
  668.         }*/
  669.     }
  670.     void collide_top(entity* other, double speed){
  671.         if( !opened ){
  672.             if( other->type == 1 ){
  673.                 other->yspeed = 0;
  674.                 other->location.y = location.y - h;
  675.             }
  676.             else{
  677.                 other-> yspeed = 0;
  678.                 other->location.y = location.y - other->h - h;
  679.             }
  680.         }
  681.     }
  682.     void collide_bottom(entity* other, double speed){
  683.         if( !opened ){
  684.             other->location.y = location.y + h + other->h;
  685.             other->yspeed = 0;
  686.  
  687.         }
  688.     }
  689.     void reset(){
  690.         opened = false;
  691.     }
  692.     void onframe(){
  693.         updatetime(0);
  694.         if( location.imageindex < 1 ){
  695.             opened = false;
  696.             location.imagespeed = 0;
  697.             location.imageindex = 0;
  698.  
  699.         }
  700.         if( location.imageindex >= sprite::get(location.spriteindex).length - 1 )
  701.             location.imagespeed = 0;
  702.  
  703.     }
  704.     void open(){
  705.         if( !opened ){
  706.             location.imagespeed = 1;
  707.             location.imageindex = 1;
  708.             opened = true;
  709.         }
  710.     }
  711.  
  712. };
  713.  
  714. struct button : entity{
  715.     std::string color;
  716.     bool onbutton = false;
  717.     button( int x, int y, std::string color ): entity( x, y, 0, true ){
  718.         location.spriteindex = sprite::get("button_" + color);
  719.         button::color = color;
  720.         w = 7;
  721.         h = 1;
  722.         location.imagespeed = 0;
  723.         location.imageindex = 0;
  724.  
  725.         entities.push_back( this );
  726.         type = 4;
  727.         onbutton = false;
  728.     }
  729.     void collide_left(entity* other, double speed){}
  730.     void collide_right(entity* other, double speed){}
  731.     void collide_top(entity* other, double speed){
  732.         if( location.imageindex == 0 )
  733.             location.imageindex = 1;
  734.         location.imagespeed = 1;
  735.         if( !onbutton ){
  736.             for( size_t i = 0; i < entities.size(); ++i ){
  737.                 if( entities[i]->type == 3 ){
  738.                     trapdoor* t = (trapdoor*)entities[i];
  739.                     if( t->color == color )
  740.                         t->open();
  741.                 }
  742.             }
  743.  
  744.         }
  745.  
  746.         onbutton = true;
  747.     }
  748.     void collide_bottom(entity* other, double speed){}
  749.     void reset(){}
  750.     void onframe(){
  751.         updatetime(0);
  752.         if( location.imageindex == 0 ){
  753.             location.imagespeed = 0;
  754.         }
  755.  
  756.         if( !onbutton && location.imageindex > 0 ){
  757.             location.imagespeed = -1;
  758.         }
  759.         if( location.imageindex >= sprite::get(location.spriteindex).length - 1 ){
  760.             location.imagespeed = 0;
  761.             location.imageindex = sprite::get(location.spriteindex).length - 1;
  762.  
  763.         }
  764.         onbutton = false;
  765.  
  766.     }
  767.  
  768. };
  769.  
  770. double timemult = 1.1;
  771. int mytime = 0;
  772.  
  773. struct dilator : entity{
  774.     double amount;
  775.     bool cangrab;
  776.     dilator( int x, int y, double amt ): entity( x, y, 0, false ){
  777.         location.spriteindex = sprite::get("pickup_dilator");
  778.  
  779.         w = 8;
  780.         h = 8;
  781.         location.imagespeed = 0;
  782.         location.imageindex = 0;
  783.         amount = amt;
  784.  
  785.         entities.push_back( this );
  786.         type = 5;
  787.         cangrab = true;
  788.     }
  789.     void collide_left(entity* other, double speed){}
  790.     void collide_right(entity* other, double speed){}
  791.     void collide_top(entity* other, double speed){
  792.         if( cangrab && other->type == 1 ){
  793.             cangrab = false;
  794.             timemult *=amount;
  795.             amount = 1;
  796.             location.visible = false;
  797.         }
  798.     }
  799.     void collide_bottom(entity* other, double speed){}
  800.     void reset(){}
  801.     void onframe(){
  802.         updatetime(0);
  803.     }
  804. };
  805.  
  806.  
  807. struct roomexit : entity{
  808.     std::string linkedroom;
  809.     roomexit( int x, int y, std::string link ): entity( x, y, 0, false ){
  810.         location.spriteindex = sprite::get("exit");
  811.  
  812.         w = 8;
  813.         h = 48/2;
  814.         location.imagespeed = 0;
  815.         location.imageindex = 0;
  816.         linkedroom = link;
  817.  
  818.         entities.push_back( this );
  819.         type = 7;
  820.     }
  821.     void collide_left(entity* other, double speed){}
  822.     void collide_right(entity* other, double speed){}
  823.     void collide_top(entity* other, double speed){
  824.         levelloaded->unload();
  825.         level::get( linkedroom ).load();
  826.     }
  827.     void collide_bottom(entity* other, double speed){}
  828.     void reset(){}
  829.     void onframe(){
  830.         updatetime(0);
  831.     }
  832. };
  833.  
  834.  
  835. struct crate : entity {
  836.     double gravity;
  837.     bool onground;
  838.     crate( int x, int y ) : entity( x, y, 0, false ){
  839.         location.x = x;
  840.         location.y = y;
  841.         location.rotation = 0;
  842.         location.imageindex = 0;
  843.         location.spriteindex = sprite::get("block");
  844.         onground = false;
  845.  
  846.         xspeed = yspeed = 0;
  847.         gravity = .04;
  848.         entities.push_back( this );
  849.         w = h = 15.5;
  850.         type = 2;
  851.     }
  852.     void reset(){
  853.         onground = false;
  854.  
  855.         xspeed = yspeed = 0;
  856.     }
  857.     void collide_left(entity* other, double speed){
  858.         if( other->type == 1 ){
  859.              xspeed = .3*speed;
  860.             other->xspeed = 0;
  861.             other->location.x = location.x - w - other->w;
  862.         }
  863.         else{
  864.             other->location.x = location.x - w - other->w;
  865.             other->xspeed = 0;
  866.             xspeed = .3*speed;
  867.         }
  868.     }
  869.     void collide_right(entity* other, double speed){
  870.         if( other->type == 1 ){
  871.              xspeed = .3*speed;
  872.             other->xspeed = 0;
  873.             other->location.x = location.x + w + other->w;
  874.         }
  875.         else{
  876.             other->location.x = location.x + w + other->w;
  877.             other->xspeed = 0;
  878.             xspeed = .3*speed;
  879.         }
  880.     }
  881.     void collide_top(entity* other, double speed){
  882.         if( other->type == 1 ){
  883.             yspeed += .3*speed;
  884.             other->yspeed = 0;
  885.             other->location.y = location.y - h;
  886.         }
  887.         else{
  888.             other-> yspeed = 0;
  889.             other->location.y = location.y - other->h - h;
  890.             yspeed += .3*speed;
  891.         }
  892.     }
  893.     void collide_bottom(entity* other, double speed){
  894.         if( other->type == 1 ){
  895.             yspeed += .3*speed;
  896.             other->yspeed = 0;
  897.             printf("%f\t%f\n", location.y, location.y + h+32);
  898.             other->location.y = location.y + h+32;
  899.  
  900.         }
  901.         else{
  902.             other->location.y = location.y + h + other->h;
  903.             other->yspeed = 0;
  904.             yspeed += .3*speed;
  905.  
  906.         }
  907.     }
  908.  
  909.  
  910.     void onframe(){
  911.         updatetime(0);
  912.         if( xspeed == 0 ) location.x = floor( location.x );
  913.         if( onground ) xspeed *= .98;
  914.         yspeed += gravity;
  915.         location.x += xspeed;
  916.         location.y += yspeed;
  917.         if( levelloaded != 0 ){
  918.             int px = location.x / 16;
  919.             int py = location.y / 16;
  920.             onground = false;
  921.             for( int i = px - 2; i <= px + 2; ++i ){
  922.                 for( int j = py - 3; j <= py + 3; ++j ){
  923.                     if( levelloaded->get_tile(i, j).type == -1 ) continue;
  924.                     int hazard = levelloaded->get_tile(i, j).hazard;
  925.  
  926.                     if( (location.y + h >= j * 16 && location.y - h < (j+1) * 16) ){
  927.                         if( (location.x+w-1 > i * 16 && location.x-w+1 < (i+1)*16 ) ){
  928.                             if( yspeed >= 0 && levelloaded->get_tile(i, j-1).type == -1 ){
  929.                                 onground=true;
  930.                                 yspeed = 0;
  931.                                 location.y = ( j ) * 16 - h;
  932.                             }
  933.                             if( yspeed < 0 && levelloaded->get_tile(i, j+1).type == -1){
  934.                                     //printf("\n\n\nBONK\n\n\n");
  935.                                 yspeed = 0;
  936.                                 location.y = ( j + 1 ) * 16+1 + h;
  937.                             }
  938.  
  939.                         }
  940.  
  941.                     }
  942.                     if((location.y + h > j * 16 && location.y - h < (j+1) * 16) ){
  943.                         if( location.x - w <= (i+1)*16 && location.x + w > i*16 ){
  944.                             if( xspeed < 0 && levelloaded->get_tile(i + 1, j).type == -1 ){
  945.                                 location.x = i * 16 + 16 + w;
  946.                                 xspeed = 0;
  947.                             }
  948.                         }
  949.                         if( location.x + w >= i*16 && location.x - w < (i+1)*16 ){
  950.                             if( xspeed > 0&& levelloaded->get_tile(i - 1, j).type == -1 ){
  951.                                 location.x = i * 16 - 1 - w;
  952.                                 xspeed = 0;
  953.                             }
  954.                         }
  955.                     }
  956.                 }
  957.             }
  958.         }
  959.         if( levelloaded != 0 ){
  960.             int px = location.x / 16;
  961.             int py = location.y / 16;
  962.             for( size_t i = 0; i < entities.size(); ++i ){
  963.                 if( entities[i] == this ) continue;
  964.                 if( (location.y+h >= entities[i]->location.y-entities[i]->h && location.y - h < entities[i]->location.y+entities[i]->h) ){
  965.                     if( (location.x+w-5 > entities[i]->location.x-entities[i]->w && location.x-w+5 < entities[i]->location.x+entities[i]->w ) ){
  966.  
  967.                         if( yspeed < 0){
  968.                             entities[i]->collide_bottom( this, yspeed );
  969.                         }
  970.                     }
  971.                 }
  972.                 if( (location.y+h >= entities[i]->location.y-entities[i]->h && location.y - h < entities[i]->location.y+entities[i]->h) ){
  973.                     if( (location.x+w-4 > entities[i]->location.x-entities[i]->w && location.x-w+4 < entities[i]->location.x+entities[i]->w ) ){
  974.  
  975.                         if( yspeed >= 0){
  976.                             entities[i]->collide_top( this, yspeed );
  977.                             if( yspeed == 0 ){
  978.                                 onground = true;
  979.                             }
  980.                         }
  981.  
  982.                     }
  983.                 }
  984.                 if((location.y + h > entities[i]->location.y-entities[i]->h+1 && location.y - h < entities[i]->location.y+entities[i]->h - 1) ){
  985.                     if( location.x - w + 1 <= entities[i]->location.x+entities[i]->w && location.x + w - 1> entities[i]->location.x-entities[i]->w ){
  986.                         if( xspeed < 0){
  987.                             entities[i]->collide_right( this, xspeed );
  988.                         }
  989.                     }
  990.                     if( location.x + w - 1 >= entities[i]->location.x-entities[i]->w && location.x - w + 1 < entities[i]->location.x+entities[i]->w ){
  991.                         if( xspeed > 0 ){
  992.                             entities[i]->collide_left( this, xspeed );
  993.                         }
  994.                     }
  995.                 }
  996.             }
  997.  
  998.         }
  999.     }
  1000. };
  1001.  
  1002. struct player : entity{
  1003.     double gravity;
  1004.     int sprite_idle;
  1005.     int sprite_run_start;
  1006.     int sprite_run;
  1007.     int sprite_jump;
  1008.     int sprite_ascending;
  1009.     int sprite_descend_start;
  1010.     int sprite_descending;
  1011.     int sprite_impact;
  1012.     int sprite_throw;
  1013.     int xmovement;
  1014.     bool onground;
  1015.     int cntr;
  1016.  
  1017.     void collide_left(entity* other, double speed){
  1018.     }
  1019.     void collide_right(entity* other, double speed){
  1020.     }
  1021.     void collide_top(entity* other, double speed){
  1022.     }
  1023.     void collide_bottom(entity* other, double speed){
  1024.     }
  1025.  
  1026.     player( int x, int y ) : entity( x, y, 0, true ){
  1027.  
  1028.         sprite_idle = sprite::get( "player_idle" ).id;
  1029.         sprite_run_start = sprite::get( "player_run_start" ).id;
  1030.         sprite_run = sprite::get( "player_run" ).id;
  1031.         sprite_jump = sprite::get( "player_jump" ).id;
  1032.         sprite_ascending = sprite::get( "player_ascending" ).id;
  1033.         sprite_descend_start = sprite::get( "player_descend_start" ).id;
  1034.         sprite_descending = sprite::get( "player_descending" ).id;
  1035.         sprite_impact = sprite::get( "player_impact" ).id;
  1036.         sprite_throw = sprite::get( "player_throw" ).id;
  1037.  
  1038.         location.x = x;
  1039.         location.y = y;
  1040.         location.rotation = 0;
  1041.         location.imageindex = 0;
  1042.         location.spriteindex = sprite_idle;
  1043.         xmovement=0;
  1044.         onground = false;
  1045.  
  1046.         xspeed = yspeed = 0;
  1047.         gravity = .04;
  1048.         cntr = 0;
  1049.         w = 10;
  1050.         h = 32;
  1051.         type = 1;
  1052.         entities.push_back(this);
  1053.     }
  1054.     void move_left(){
  1055.         xmovement = xmovement | 1;
  1056.         //printf("a %d\n", xmovement);
  1057.     }
  1058.     void move_right(){
  1059.         xmovement |= 2;
  1060.     }
  1061.     void move_left_halt(){
  1062.         xmovement &= ~1;
  1063.     }
  1064.     void move_right_halt(){
  1065.         xmovement &= ~2;
  1066.     }
  1067.     void move_jump(){
  1068.         if( onground && (location.spriteindex == sprite_idle || location.spriteindex == sprite_run || location.spriteindex == sprite_run_start )){
  1069.             location.spriteindex = sprite_jump;
  1070.             location.imageindex = 0;
  1071.         }
  1072.     }
  1073.  
  1074.     void reset(){
  1075.         xspeed = yspeed = 0;
  1076.         xmovement=0;
  1077.         onground = false;
  1078.     }
  1079.  
  1080.     void onframe(){
  1081.         //printf("sprite: %d\t%d\t%d\t%d\n", location.spriteindex, sprite_descend_start, sprite_descending, sprite_impact );
  1082.         //if( cntr == 0 )
  1083.             updatetime(0);
  1084.         cntr = ( cntr + 1 ) % 3;
  1085.         yspeed += gravity;
  1086.  
  1087.  
  1088.         location.x += xspeed;
  1089.         location.y += yspeed;
  1090.  
  1091.  
  1092.         if( levelloaded != 0 ){
  1093.             int px = location.x / 16;
  1094.             int py = location.y / 16;
  1095.             onground = false;
  1096.             for( int i = px - 2; i <= px + 2; ++i ){
  1097.                 for( int j = py - 3; j <= py + 3; ++j ){
  1098.                     if( levelloaded->get_tile(i, j).type == -1 ) continue;
  1099.                     int hazard = levelloaded->get_tile(i, j).hazard;
  1100.  
  1101.                     if( (location.y >= j * 16 && location.y - 32 < (j+1) * 16) ){
  1102.  
  1103.  
  1104.                         if( (location.x+8 > i * 16 && location.x-8 < (i+1)*16 ) ){
  1105.                             if( yspeed >= 0 && levelloaded->get_tile(i, j-1).type == -1 ){
  1106.                                 onground=true;
  1107.                                 yspeed = 0;
  1108.                                 location.y = ( j ) * 16;
  1109.                                 if( hazard ) printf("OW OW OW\n");
  1110.                                 if( location.spriteindex == sprite_descending ){
  1111.                                     location.spriteindex = sprite_impact;
  1112.                                     location.imageindex = 0;
  1113.                                     sound::get( "land" ).play();
  1114.                                 }
  1115.                                 else if( location.spriteindex == sprite_descend_start ){
  1116.                                     location.spriteindex = sprite_idle;
  1117.                                     location.imageindex = 0;
  1118.                                 }
  1119.  
  1120.                             }
  1121.                             if( yspeed < 0 && levelloaded->get_tile(i, j+1).type == -1){
  1122.                                     //printf("\n\n\nBONK\n\n\n");
  1123.                                 yspeed = 0;
  1124.                                 location.y = ( j + 3 ) * 16+1;
  1125.                                 if( hazard ) printf("OW OW OW\n");
  1126.  
  1127.                             }
  1128.  
  1129.                         }
  1130.                         if((location.y > j * 16 +1 && location.y - 32 < (j+1) * 16 - 1) ){
  1131.                             if( location.x - 10 <= (i+1)*16 && location.x + 10 > i*16 ){
  1132.                                 if( xspeed < 0 && levelloaded->get_tile(i + 1, j).type == -1 ){
  1133.                                     location.x = i * 16 + 26;
  1134.                                     xspeed = 0;
  1135.                                     if( hazard ) printf("OW OW OW\n");
  1136.                                 }
  1137.                             }
  1138.                             if( location.x + 10 >= i*16 && location.x - 10 < (i+1)*16 ){
  1139.                                 if( xspeed > 0&& levelloaded->get_tile(i - 1, j).type == -1 ){
  1140.                                     location.x = i * 16 - 11;
  1141.                                     xspeed = 0;
  1142.                                     if( hazard ) printf("OW OW OW\n");
  1143.                                 }
  1144.                             }
  1145.  
  1146.                         }
  1147.  
  1148.  
  1149.  
  1150.                     }
  1151.  
  1152.                 }
  1153.  
  1154.  
  1155.                     /*if( (location.y > j * 16 && location.y - 32 <= (j+1) * 16) && (location.x+10 > i * 16 && location.x < (i+1)*16 ) ){
  1156.                         onground=true;
  1157.                         yspeed = 0;
  1158.                         location.y = ( j ) * 16;
  1159.                         if( location.spriteindex == sprite_descending ){
  1160.                             location.spriteindex = sprite_impact;
  1161.                             location.imageindex = 0;
  1162.                         }
  1163.                         else if( location.spriteindex == sprite_descend_start ){
  1164.                             location.spriteindex = sprite_idle;
  1165.                             location.imageindex = 0;
  1166.                         }
  1167.                     }
  1168.  
  1169.                 }*/
  1170.             }
  1171.  
  1172.             /*double tx = location.x / 16;
  1173.             double ty = location.y / 16;
  1174.  
  1175.             int hitbot = ty>py && ((levelloaded->get_tile(px, py).type != -1) || ( floor( location.x ) != location.x && levelloaded->get_tile(px+1, py).type != -1 ));
  1176.             int hitleft = tx<px &&((levelloaded->get_tile(px, py).type != -1)||(levelloaded->get_tile(px, py-1).type != -1));
  1177.             int hitright = tx>px && ((levelloaded->get_tile(px+1, py).type != -1)||(levelloaded->get_tile(px+1, py-1).type != -1)) ;
  1178.             int hittop = ty<py && ((levelloaded->get_tile(px, py - 2).type != -1) || ( floor( location.x ) != location.x && levelloaded->get_tile(px+1, py -2).type != -1 ));
  1179.  
  1180.             onground=false;
  1181.             if( hitbot ){
  1182.  
  1183.             }
  1184.             if( hitright ){
  1185.                 xspeed = 0;
  1186.                 location.x = px;
  1187.             }
  1188.             if( hitleft ){
  1189.                 xspeed = 0;
  1190.                 location.x = px;
  1191.             }*/
  1192.  
  1193.  
  1194.         }
  1195.  
  1196.         if( levelloaded != 0 ){
  1197.             int px = location.x / 16;
  1198.             int py = location.y / 16;
  1199.             for( size_t i = 0; i < entities.size(); ++i ){
  1200.                 if( (location.y >= entities[i]->location.y-entities[i]->h && location.y - 32 < entities[i]->location.y+entities[i]->h) ){
  1201.                     if( (location.x+5 > entities[i]->location.x-entities[i]->w && location.x-5 < entities[i]->location.x+entities[i]->w ) ){
  1202.  
  1203.                         if( yspeed < 0){
  1204.                             entities[i]->collide_bottom( this, yspeed );
  1205.                         }
  1206.                     }
  1207.                 }
  1208.                 if( (location.y >= entities[i]->location.y-entities[i]->h && location.y - 32 < entities[i]->location.y+entities[i]->h) ){
  1209.                     if( (location.x+5 > entities[i]->location.x-entities[i]->w && location.x-5 < entities[i]->location.x+entities[i]->w ) ){
  1210.  
  1211.                         if( yspeed >= 0){
  1212.                             entities[i]->collide_top( this, yspeed );
  1213.                             if( yspeed == 0 ){
  1214.                                 onground = true;
  1215.                                 if( location.spriteindex == sprite_descending ){
  1216.                                     location.spriteindex = sprite_impact;
  1217.                                     location.imageindex = 0;
  1218.                                     sound::get( "land" ).play();
  1219.                                 }
  1220.                                 else if( location.spriteindex == sprite_descend_start ){
  1221.                                     location.spriteindex = sprite_idle;
  1222.                                     location.imageindex = 0;
  1223.                                 }
  1224.                             }
  1225.                         }
  1226.  
  1227.                     }
  1228.                     if((location.y > entities[i]->location.y-entities[i]->h+2 && location.y - 32 < entities[i]->location.y+entities[i]->h - 2) ){
  1229.                         if( location.x - 8 <= entities[i]->location.x+entities[i]->w && location.x + 8 > entities[i]->location.x-entities[i]->w ){
  1230.                             if( xspeed < 0){
  1231.                                 entities[i]->collide_right( this, xspeed );
  1232.                             }
  1233.                         }
  1234.                         if( location.x + 8 >= entities[i]->location.x-entities[i]->w && location.x - 8 < entities[i]->location.x+entities[i]->w ){
  1235.                             if( xspeed > 0 ){
  1236.                                 entities[i]->collide_left( this, xspeed );
  1237.                             }
  1238.                         }
  1239.                     }
  1240.                 }
  1241.  
  1242.             }
  1243.         }
  1244.  
  1245.         if( onground  ){
  1246.             if( location.spriteindex != sprite_jump )
  1247.                 xspeed = 0;
  1248.             else
  1249.                 xspeed *= .99;
  1250.         }
  1251.  
  1252.  
  1253.         //printf("%d", onground);
  1254.         //printf("sprite: %d\t%d\t%d\t%d\n", location.spriteindex, sprite_descend_start, sprite_descending, sprite_impact );
  1255.         if( (xmovement & 1) && onground && ( location.spriteindex == sprite_idle || location.spriteindex == sprite_run ) ){
  1256.  
  1257.             xspeed += -.6;
  1258.  
  1259.  
  1260.             if( location.spriteindex == sprite_idle ){ location.spriteindex = sprite_run_start; location.imageindex = 2; }
  1261.             location.xscale = -1;
  1262.              //printf("h4h4h4");
  1263.         }
  1264.         if( (xmovement & 2) && onground && ( location.spriteindex == sprite_idle || location.spriteindex == sprite_run ) ){
  1265.             xspeed += .6;
  1266.  
  1267.             location.xscale = 1;
  1268.             if( location.spriteindex == sprite_idle ){ location.spriteindex = sprite_run_start; location.imageindex = 2; }
  1269.              //printf("h5h5h5");
  1270.         }
  1271.         //printf("Image Index: %f\n", xspeed );
  1272.  
  1273.         if( (xmovement & 1) && !onground ){
  1274.             xspeed += -.008;
  1275.             if( location.spriteindex == sprite_idle ){ location.spriteindex = sprite_run_start; location.imageindex = 2; }
  1276.             location.xscale = -1;
  1277.         }
  1278.         if( (xmovement & 2) && !onground ){
  1279.             xspeed += .008;
  1280.             location.xscale = 1;
  1281.             if( location.spriteindex == sprite_idle ){ location.spriteindex = sprite_run_start; location.imageindex = 2; }
  1282.         }
  1283.         //printf("Image Index: %f\n", xspeed );
  1284.  
  1285.         if( yspeed > 0 && location.spriteindex != sprite_descending ){
  1286.             if( location.spriteindex != sprite_descend_start ){
  1287.                 location.spriteindex = sprite_descend_start;
  1288.                 location.imageindex = 0;
  1289.             }
  1290.             if( location.spriteindex == sprite_descend_start && location.imageindex >= sprite::get(sprite_descend_start).length - 1 ){
  1291.                 location.spriteindex = sprite_descending;
  1292.                 location.imageindex = 0;
  1293.             }
  1294.         }
  1295.  
  1296.  
  1297.  
  1298.         if( location.spriteindex == sprite_impact && location.imageindex == sprite::get(sprite_impact).length - 1){
  1299.             location.spriteindex = sprite_idle;
  1300.             location.imageindex = 0;
  1301.         }
  1302.         if( location.spriteindex == sprite_jump && location.imageindex == 4){
  1303.             yspeed = -1.9;
  1304.             //location.y --;
  1305.  
  1306.             sound::get( "jump" ).play();
  1307.         }
  1308.         if( location.spriteindex == sprite_jump && location.imageindex == sprite::get(sprite_jump).length - 1){
  1309.             location.spriteindex = sprite_ascending;
  1310.             location.imageindex = 0;
  1311.         }
  1312.         if( onground && location.spriteindex == sprite_ascending ){
  1313.             location.spriteindex = sprite_idle;
  1314.             location.imageindex = 0;
  1315.         }
  1316.  
  1317.  
  1318.         if( location.spriteindex == sprite_run_start && location.imageindex >= sprite::get(sprite_run_start).length - 1 ){
  1319.             //printf("Image Index: %f\n", xspeed );
  1320.             if( xspeed != 0){
  1321.                 location.spriteindex = sprite_run;
  1322.                 location.imageindex = 0;
  1323.             }
  1324.             else{
  1325.                 location.spriteindex = sprite_idle;
  1326.                 location.imageindex = 0;
  1327.             }
  1328.         }
  1329.         if( location.spriteindex == sprite_run && xspeed == 0 ){
  1330.             location.spriteindex = sprite_idle;
  1331.             location.imageindex = 0;
  1332.         }
  1333.     }
  1334. };
  1335.  
  1336. bool timeresetting = false;
  1337. struct checkpoint : entity{
  1338.     checkpoint( int x, int y ): entity( x, y, 0, false ){
  1339.         location.spriteindex = sprite::get("pickup_checkpoint");
  1340.  
  1341.         w = 8;
  1342.         h = 8;
  1343.         location.imagespeed = 0;
  1344.         location.imageindex = 0;
  1345.  
  1346.         entities.push_back( this );
  1347.         type = 6;
  1348.     }
  1349.     void collide_left(entity* other, double speed){}
  1350.     void collide_right(entity* other, double speed){}
  1351.     void collide_top(entity* other, double speed){
  1352.         timeresetting = true;
  1353.     }
  1354.     void collide_bottom(entity* other, double speed){}
  1355.     void reset(){}
  1356.     void onframe(){
  1357.         updatetime(0);
  1358.     }
  1359. };
  1360.  
  1361.  
  1362. bool hasdrawnnumber = false;
  1363. int hasdrawnnumbertube;
  1364. int hasdrawnnumbernum;
  1365.  
  1366. void drawnumber(int number, int padding, int drawnum = true){
  1367.     if( !hasdrawnnumber ){
  1368.         hasdrawnnumbernum = sprite::get("numbers").id;
  1369.         hasdrawnnumbertube = sprite::get("tube").id;
  1370.         hasdrawnnumber = true;
  1371.     }
  1372.     glTranslated( padding*21.0/2.0-10+5,0,0 );
  1373.     for( int i = 0; i < padding; ++i ){
  1374.  
  1375.         sprite::get(hasdrawnnumbertube).draw( 0 );
  1376.         if( drawnum )
  1377.         sprite::get(hasdrawnnumbernum).draw( number%10 );
  1378.         number /= 10;
  1379.         glTranslated( -21,0,0 );
  1380.         if( i == 1 )
  1381.             glTranslated( -10,0,0 );
  1382.     }
  1383. }
  1384.  
  1385. void level::unload(){
  1386.     for( int i = 0; i < entities.size(); ++i ){
  1387.         delete entities[i];
  1388.     }
  1389.     entities.clear();
  1390.     timemult = 1.1;
  1391.     levelloaded = 0;
  1392. }
  1393. player* playa = 0;
  1394. void level::load(){
  1395.     timemult = 1.1;
  1396.     levelloaded = this;
  1397.     for( int i = 0; i < objs.size(); ++i ){
  1398.         if( objs[i].type == "player" ){
  1399.             playa = new player(objs[i].x, objs[i].y);
  1400.         }
  1401.         else if( objs[i].type == "crate" ){
  1402.             new crate(objs[i].x, objs[i].y);
  1403.         }
  1404.         else if( objs[i].type.substr(0, 6)  == "button" ){
  1405.             new button(objs[i].x, objs[i].y, objs[i].type.substr(6) );
  1406.         }
  1407.         else if( objs[i].type.substr(0, 8)  == "trapdoor" ){
  1408.             new trapdoor(objs[i].x, objs[i].y, objs[i].type.substr(8) );
  1409.         }
  1410.         else if( objs[i].type == "dilator" ){
  1411.             new dilator(objs[i].x, objs[i].y, .5 );
  1412.         }
  1413.         else if( objs[i].type == "checkpoint" ){
  1414.             new checkpoint(objs[i].x, objs[i].y ) ;
  1415.         }
  1416.         else if( objs[i].type.substr(0, 5) == "exit_" ){
  1417.             new roomexit(objs[i].x, objs[i].y, objs[i].type.substr(5) );
  1418.         }
  1419.     }
  1420. }
  1421.  
  1422.  
  1423. int main(){
  1424.  
  1425.         const SDL_VideoInfo* info = 0;
  1426.         if( SDL_Init( SDL_INIT_EVERYTHING ) < 0 ) return 1;
  1427.         if( !(info = SDL_GetVideoInfo( ))) return 2;
  1428.         IMG_Init(IMG_INIT_PNG);
  1429.         int bpp = info->vfmt->BitsPerPixel;
  1430.  
  1431.         SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 );
  1432.         SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 6 );
  1433.         SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 );
  1434.         SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
  1435.         SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
  1436.         SDL_Surface* screen;
  1437.         if( !(screen=SDL_SetVideoMode( WIDTH*SCALE, HEIGHT*SCALE, bpp, SDL_OPENGL | SDL_RESIZABLE  ) )) return 3;
  1438.  
  1439.         glOrtho( 0, WIDTH, HEIGHT, 0, -pow( 2, 15 ) , pow( 2, 15 ) );
  1440.  
  1441.         glMatrixMode( GL_PROJECTION );
  1442.         glLoadIdentity( );
  1443.         glPixelStorei(GL_UNPACK_ALIGNMENT,4);
  1444.  
  1445.         glTexEnvf( GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_MODULATE );
  1446.  
  1447.         glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
  1448.         glEnable(GL_BLEND);
  1449.  
  1450.         AudioMan = new audiomanager();
  1451.  
  1452.  
  1453.  
  1454.     std::string buff = read_file_to_buffer( "loadscript.lua" );
  1455.     printf("%s", buff.c_str());
  1456.     Lua L( buff.c_str(), "Configuration", 0 );
  1457.     L.funcreg<int, const char*, int, int, int, int, int, int, image::add >("image_strip_add");
  1458.     L.funcreg<int, const char*, int, int, int, int, int, int, sprite::add >("sprite_add");
  1459.     L.funcreg<int, const char*, const char*, int, int, sound::add >("sound_add");
  1460.     L.funcreg<int, const char*, int, tileset::add >("tileset_add");
  1461.     L.funcreg<int, const char*, tileset::add_animation >("tileset_animation_start");
  1462.     L.funcreg<int, int, int, tileset::add_animation_frame >("tileset_animation_add");
  1463.     L.funcreg<int, int, tileset::add_animation_finish >("tileset_animation_finish");
  1464.     L.funcreg<int, const char*, const char*, level::add >("level_add");
  1465.  
  1466.  
  1467.     //L.funcreg<int, const char*, const char*, int, int, print >("p_rint");
  1468.     //L.funcreg<int, const char*, print2 >("p_rint");
  1469.  
  1470.     L.run();
  1471.  
  1472.        //entity e(200, 20);
  1473.         //double gravity = .05;
  1474.        // double vs = 0;
  1475.        // double hs = 1;
  1476.         //int frames = 0;
  1477.         //e.location.spriteindex = sprite::get("trapdoor_red").id;
  1478.        // e.location.imageindex = 0;
  1479.         double camerax, cameray, cameraxp, camerayp;
  1480.  
  1481.  
  1482.  
  1483.         SDL_Event event;
  1484.         sound::get("bgm").play();
  1485.         //level l = level::get("test");
  1486.         framelimiter FPS(16);
  1487.         /*player p( 16*9, 16*20 );
  1488.         crate c1(  16*19, 16*17 );
  1489.         //crate c2(  16*13, 16*17 );
  1490.         crate c3(  16*22, 16*13 );
  1491.         crate c4(  16*22, 16*13 );
  1492.         crate c5(  16*22, 16*13 );
  1493.         crate c6(  16*22, 16*13 );
  1494.  
  1495.  
  1496.  
  1497.         button b1 ( 16*28, 16*18, "red");
  1498.         button b2 ( 16*22, 16*25, "green");
  1499.         checkpoint ch1 ( 16*32, 16*16 );
  1500.         dilator d1 ( 16*36, 16*17, .5 );
  1501.  
  1502.  
  1503.         trapdoor t1 ( 16*22, 16*20+1, "red");
  1504.         trapdoor t2 ( 16*22, 16*14+1, "green");*/
  1505.  
  1506.  
  1507.  
  1508.         //levelloaded = &
  1509.         level::get("lvl1").load();
  1510.  
  1511.         camerax = cameraxp = -playa->location.x+WIDTH/2;
  1512.         cameray = camerayp = -playa->location.y+HEIGHT/2+20;
  1513.         double frames = 0;
  1514.         bool rewinding = false;
  1515.         double rewindcount = 0;
  1516.         /*bool chopping = false;
  1517.         double chopnum = 0;
  1518.         while( true ){
  1519.             while(SDL_PollEvent(&event)) {
  1520.  
  1521.                 switch( event.type ){
  1522.                     case SDL_KEYDOWN:{
  1523.                         switch( event.key.keysym.sym ){
  1524.                             case SDLK_SPACE: chopping = true;
  1525.  
  1526.                         default: break;
  1527.                         }
  1528.                     } break; //major facepalm
  1529.                     case SDL_KEYUP:{
  1530.                         switch( event.key.keysym.sym ){
  1531.                             case SDLK_SPACE: chopping = false;
  1532.  
  1533.                         default: break;
  1534.                         }
  1535.                     }
  1536.                     default: break;
  1537.  
  1538.                 }
  1539.             }
  1540.             if( chopping ){ sound::get("bgm").setrip( (cos(chopnum * 3.14159*10)+1)/3.0+.2); }
  1541.             else sound::get("bgm").setrip( 0 );
  1542.             chopnum += .021;
  1543.             FPS.tick();
  1544.         }*/
  1545.         unsigned int flasher = 0;
  1546.         while( true ){
  1547.                 flasher++;
  1548.             camerax = camerax + ( (-playa->location.x+WIDTH/2) - camerax ) / 4;
  1549.             cameray = cameray + ( (-playa->location.y+HEIGHT/2+20) - cameray ) / 4;
  1550.  
  1551.             FPS.tick();
  1552.             tileframe++;
  1553.             while(SDL_PollEvent(&event)) {
  1554.                 if( !rewinding ){
  1555.                 switch( event.type ){
  1556.                     case SDL_KEYDOWN:{
  1557.                         switch( event.key.keysym.sym ){
  1558.                             case SDLK_LEFT: playa->move_left(); break;
  1559.                             case SDLK_RIGHT: playa->move_right(); break;
  1560.                             case SDLK_UP: playa->move_jump(); break;
  1561.                             //case SDLK_SPACE: t1.open(); break;
  1562.  
  1563.  
  1564.                         default: break;
  1565.                         }
  1566.                     } break; //major facepalm
  1567.                     case SDL_KEYUP:{
  1568.                         switch( event.key.keysym.sym ){
  1569.                             case SDLK_LEFT: playa->move_left_halt(); break;
  1570.                             case SDLK_RIGHT: playa->move_right_halt(); break;
  1571.  
  1572.                         default: break;
  1573.                         }
  1574.                     }
  1575.                     default: break;
  1576.  
  1577.                 }
  1578.                 }
  1579.             }
  1580.             if( !rewinding ){
  1581.                 for( int i = 0; i < 10; ++i ){
  1582.                     for( size_t k = 0; k < entities.size(); ++k ){
  1583.                         entities[k]->onframe();
  1584.                     }
  1585.  
  1586.  
  1587.                 }
  1588.                 rewindcount = 0;
  1589.                 frames+=timemult;
  1590.             }
  1591.             else{
  1592.                 if( rewindcount > 1 ) rewindcount = 1;
  1593.  
  1594.                 for( size_t k = 0; k < entities.size(); ++k ){
  1595.                     entities[k]->rewind( rewindcount );
  1596.                 }
  1597.                 rewindcount+=.021;
  1598.                 frames--;
  1599.                 sound::get("bgm").setrip( (cos(rewindcount * 3.14159*10)+1)/3.0+.2);
  1600.  
  1601.             }
  1602.  
  1603.  
  1604.  
  1605.             if( frames > 200 ){
  1606.                 rewinding = true;
  1607.                 rewindcount = 0;
  1608.                 sound::get("rewind").play();
  1609.                 sound::get("bgm").setrip( .5);
  1610.                 frames = 0;
  1611.             }
  1612.             if( rewindcount >= 1 ){
  1613.                 rewinding = false;
  1614.  
  1615.                 for( size_t k = 0; k < entities.size(); ++k ){
  1616.                     entities[k]->rewindclear();
  1617.                 }
  1618.                 frames=0;
  1619.                 playa->reset();
  1620.                 sound::get("bgm").setrip( 0);
  1621.  
  1622.             }
  1623.             if( timeresetting ){
  1624.                     timeresetting = false;
  1625.             playa->rewindclear();
  1626.             playa->updatetime(1);
  1627.             playa->updatetime(1);
  1628.  
  1629.  
  1630.                 if( frames > 50 ){
  1631.  
  1632.                     rewinding = true;
  1633.                     rewindcount = 0;
  1634.                     sound::get("rewind").play();
  1635.                     sound::get("bgm").setrip( .5);
  1636.                 }
  1637.                 else {
  1638.  
  1639.                     for( size_t k = 0; k < entities.size(); ++k ){
  1640.                         entities[k]->rewind( 1 );
  1641.                     }
  1642.                     for( size_t k = 0; k < entities.size(); ++k ){
  1643.                         entities[k]->rewindclear();
  1644.                     }
  1645.                 }
  1646.                 frames = 0;
  1647.             }
  1648.             glMatrixMode(GL_MODELVIEW);
  1649.             glPushMatrix();
  1650.  
  1651.  
  1652.             glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
  1653.             glClearColor( 0,0,0,0 );
  1654.             glColor3ub(122, 10, 10);
  1655.             glBegin(GL_TRIANGLE_STRIP);
  1656.             glVertex2d( WIDTH, 0 );
  1657.             glVertex2d( 0, 0 );
  1658.  
  1659.             glColor3ub(85, 5, 5);
  1660.             glVertex2d( WIDTH, HEIGHT );
  1661.             glColor3ub(40, 0, 0);
  1662.             glVertex2d( 0, HEIGHT );
  1663.             glEnd();
  1664.  
  1665.  
  1666.  
  1667.             if( rewinding ){
  1668.                 glTranslated(WIDTH/2, HEIGHT/2, 0);
  1669.                 glRotated( (rand()%10-5) * (1-rewindcount), 0, 0, 1 );
  1670.                 glTranslated(-WIDTH/2, -HEIGHT/2, 0);
  1671.             }
  1672.             glTranslated( ((int)(camerax)), ((int)(cameray)), 0  );
  1673.  
  1674.             levelloaded->draw();
  1675.             for( size_t k = 0; k < entities.size(); ++k ){
  1676.                 entities[k]->draw();
  1677.             }
  1678.  
  1679.             glPopMatrix();
  1680.             glPushMatrix();
  1681.             glColor3ub(255,255,255);
  1682.             glTranslated(WIDTH/2, 20, 0 );
  1683.             if( !rewinding ){
  1684.                 //drawnumber( 1099-frames*110/20, 4 );
  1685.                 drawnumber( 1000-frames*100/20, 4 );
  1686.  
  1687.             }
  1688.             else{
  1689.                 drawnumber( 0, 4, flasher % 10 < 5 );
  1690.             }
  1691.             glPopMatrix();
  1692.             SDL_GL_SwapBuffers( );
  1693.             //SDL_Delay(30);
  1694.         }
  1695. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement