Exemplo n.º 1
0
ConfigFile::ConfigFile( std::string Filename )
{
	ALLEGRO_FILE* fileHnd;
	std::string document;
	char buf[1024];

	fileHnd = al_fopen( Filename.c_str(), "r" );
	if( fileHnd != 0 )
	{
		document.clear();
		while( !al_feof( fileHnd ) )
		{
			al_fgets( fileHnd, (char*)&buf, 1024 );
			document.append( (char*)&buf );
			memset( (void*)buf, 0, 1024 );
		}
		ParseFile( document );
		al_fclose( fileHnd );
	}
}
Exemplo n.º 2
0
void load_translation_tags(void)
{
	ALLEGRO_FILE *f = al_fopen(getResource("English.utf8"), "r");
	if (!f) {
		native_error("Couldn't load English.utf8.");
	}

	char buf[5000];

	while (al_fgets(f, buf, 5000) != NULL) {
		if (buf[strlen(buf)-1] == 0xa)
			buf[strlen(buf)-1] = 0;
		if (buf[strlen(buf)-1] == 0xd)
			buf[strlen(buf)-1] = 0;
		for (int i = 0; buf[i]; i++) {
			if (buf[i] == '^') buf[i] = '\n';
		}
		pre_translated_strings.push_back(std::string(buf));
	}

	al_fclose(f);
}
Exemplo n.º 3
0
GameLogic::GameLogic(int Width, int Height, float LogicFPS) {
	Debug = false;
	
	Display = NULL;
    EventQueue = NULL;
    Timer = NULL;
    Bitmap.Logo = NULL;
	Bitmap.Title = NULL;
    Font.Small = NULL;
    Font.Medium = NULL;
    Font.Big = NULL;
    Sound.HitWall = NULL;
    Sound.HitPaddle = NULL;
    Sound.BackgroundMusic = NULL;
    UserDataFile = NULL;
	DisplayWidth = Width;
	DisplayHeight = Height;
	TimerStep = 1.0 / LogicFPS;
    
	bool key[2] = { false, false };
    float alpha = 0;
    float colr = 0;
    float colg = 0;
    float colb = 0;
    int tick = 0;
    int menu = 0;
    int high_score = 0;
    bool restart = true;
    int score = 0, multi = 1, final_score = 1;
    bool game_over, redraw;
    char scoretxt[8] = "";
    char multitxt[4] = "";
    char final_scoretxt[16] = "";
    char hightxt[16] = "";

    // intro screen
    while (1) {
        ALLEGRO_EVENT ev;
        al_wait_for_event(EventQueue, &ev);

        if(ev.type == ALLEGRO_EVENT_TIMER) {
            // trigger redraw
            tick++;
            if(tick < 180) {
                colr = colg = colb = (0.5 * sin( (tick - 90) * ALLEGRO_PI / 180.0) + 0.5);
                alpha = 0;
            }
            else if(tick < 360) {
                alpha = (0.5 * sin( (tick + 90) * ALLEGRO_PI / 180.0) + 0.5);
                colr = colg = colb = 1;
            }
            else if(tick > 450 && tick < 630) {
                colr = colg = colb = alpha = (0.5 * cos( (tick - 90) * ALLEGRO_PI / 180.0) + 0.5);
            }
            else if(tick > 632) {
                break;
            }
            redraw = true;
        }
        else if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) {
            return;
        }
        else if(ev.type == ALLEGRO_EVENT_MOUSE_BUTTON_UP) {
            break;
        }

        if(redraw && al_is_event_queue_empty(EventQueue)) {
            redraw = false;
            al_clear_to_color(al_map_rgb_f(colr,colg,colb));
            al_draw_tinted_bitmap(Bitmap.Logo, al_map_rgba_f(alpha, alpha, alpha, alpha), (DisplayWidth - al_get_bitmap_width(Bitmap.Logo) ) / 2, (DisplayHeight - al_get_bitmap_height(Bitmap.Logo) )/ 2, 0);
            al_flip_display();
        }
    }

    al_flip_display();
    al_clear_to_color(al_map_rgb(0,0,0));

	// load hiscore info
    UserDataFile = al_fopen("assets/hiscore.txt", "r");
    if(UserDataFile) {
        char *line = (char*) malloc (17);
        line = al_fgets(UserDataFile, line, 17);
        high_score = atoi(line);
        free(line);
    }
    else {
        high_score = 0;
    }
	final_score = 0;

    sprintf(hightxt, "High: %d", high_score);
    al_fclose(UserDataFile);

    // main menu loop
    while (1) {
        ALLEGRO_EVENT ev;
        al_wait_for_event(EventQueue, &ev);

        if(ev.type == ALLEGRO_EVENT_TIMER) {
            // trigger redraw
            redraw = true;
        }
        else if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) {
			// exit if the Display is closed
            return;
        }
        else if(ev.type == ALLEGRO_EVENT_MOUSE_AXES || ev.type == ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY) {
            // track mouse movement
			if((ev.mouse.y > 350) && (ev.mouse.y < 388) && (ev.mouse.x > 250) && (ev.mouse.x < 388)) {
				menu = 1;
			}
			else {
				menu = 0;
			}
        }
        else if(ev.type == ALLEGRO_EVENT_MOUSE_BUTTON_UP) {
			// track mouse clicks
			if(menu == 1) {
				break;
			}
        }

        if(redraw && al_is_event_queue_empty(EventQueue)) {
			// process entire queue and only render if the Timer has ticked
            redraw = false;
            al_clear_to_color(al_map_rgb(0,0,0));
			al_draw_bitmap(Bitmap.Title, (DisplayWidth - al_get_bitmap_width(Bitmap.Title) ) / 2, 16, 0);
            al_draw_text(Font.Small, al_map_rgb(128,128,0), DisplayWidth / 2, 250, ALLEGRO_ALIGN_CENTRE, "Version 0.1");
			if(menu == 1) {
				al_draw_text(Font.Medium, al_map_rgb(128,0,0), DisplayWidth / 2, 350, ALLEGRO_ALIGN_CENTRE, "Play Now!");
			}
			else {
				al_draw_text(Font.Medium, al_map_rgb(128,128,0), DisplayWidth / 2, 350, ALLEGRO_ALIGN_CENTRE, "Play Now!");
			}
            al_flip_display();
        }
    }

    // seed rand function
    srand(al_get_time());

    // game wrapper lets us restart the game
    while(restart) {
		// hide the cursor
        //al_hide_mouse_cursor(Display);

		// assume we don't want to play again
        restart = false;
		
		// Base objects
		Ball StarterBall = Ball();
		Paddle StarterPaddle = Paddle(0);
		Paddle StarterPaddle2 = Paddle(DisplayHeight - 8);
		Paddle StarterPaddle3 = Paddle(0, true);
		Paddle StarterPaddle4 = Paddle(DisplayWidth - 8, true);
		        
		// TODO: load the right map

			// set Bitmap.Title
			// set base speed
			// create list of block entities
		

		// Populate entity lists
		// Remove static data when we get map loading done
		for(int i=0; i < 64; i++) {
			Brick SingleBlockyEntity = Brick((i % 16) * 40, 80 + ( (i / 16) * 10), i % 8);
			Bricks.push_back(SingleBlockyEntity);
		}
		Paddles.push_back(StarterPaddle);
		Paddles.push_back(StarterPaddle2);
		Paddles.push_back(StarterPaddle3);
		Paddles.push_back(StarterPaddle4);
		Balls.push_back(StarterBall);

		// save high score if the final score is higher
        if(final_score > high_score) {
            high_score = final_score;
            sprintf (hightxt, "High: %d", high_score);
        }

		// reset score if not a continuation

		// init hud
		
		// force initial draw
		redraw = true;
        
		// reset physics
		game_over = false;

        // main game loop
        while(1) {
            ALLEGRO_EVENT ev;
            al_wait_for_event(EventQueue, &ev);

            if(ev.type == ALLEGRO_EVENT_TIMER) {
                // game logic loop
                if(!game_over) {
					// calculate each ball's new position and check for...
					Path CurrentPath;
					for(int i = 0; i < Balls.size(); i++) {
						CurrentPath = Balls[i].GetPath(TimerStep);

						// distance traveled in axis directions in time delta t
						float NX = Balls[i].Position.DeltaX * TimerStep;
						float NY = Balls[i].Position.DeltaY * TimerStep;
						// new unencombered position
						float NewPositionX = Balls[i].Position.X + NX;
						float NewPositionY = Balls[i].Position.Y + NY;
						ClosestEntity Closest;
						Closest.Magnitude = 10000;
						// look for collisions
						for(int j = 0; j < (int)Bricks.size(); j++) {
							// only check items that haven't been hit in the most recent update
							if (!Bricks[j].HasBeenHit()) {
								Intersection Point = Bricks[j].PathIntersect(CurrentPath);
								if (Point.Type == Intersecting) {
									// mark this hit so we don't check for it again...
									// until the next update frame.
									Bricks[i].Hit = true;
									// see how far the collision is
									float Magnitude = sqrt(pow(Point.X - Balls[i].Position.X, 2) + pow(Point.Y - Balls[i].Position.Y, 2)); 
									if (Magnitude <  Closest.Magnitude) {
										// nab the closest collision so we can handle multiple collisions
										Closest.Magnitude = Magnitude;
										Closest.EntityIndex = j;
										Closest.CollisionPoint = Point;
									}
								}
							}
						}

						if (Closest.CollisionPoint.Type == Intersecting) {
							if(Bricks[Closest.EntityIndex].Harm(Balls[i].CollisionDamage)) {
		
							// TODO: play a sound

							// Update the ball to the point of collision
							Balls[i].Position.X = Closest.CollisionPoint.X;
							Balls[i].Position.Y = Closest.CollisionPoint.Y;

							// Reflect the ball in the appropriate direction
							switch(Closest.CollisionPoint.From) {
							default:
							case Top:
							case Bottom:
								Balls[i].ReflectY();
								break;
							case Left:
							case Right:
								Balls[i].ReflectX();
								break;
							}
		
							/* Find the fraction of DeltaT that had to occur before this collision
							float UnknownT = TimerStep * (Closest.Magnitude / sqrt(pow(NX,2) + pow(NY, 2)));
							// simlulate the ball movement after the collision
							Balls[i].GetPath(TimerStep - UnknownT);
							break;*/
						}

	
						if(NewPositionX > 0.0f && NewPositionX < DisplayWidth - Balls[i].Width && NewPositionY > 0.0f && NewPositionY < DisplayHeight - Balls[i].Height) {
							Balls[i].Live = true;
							Balls[i].Position.X = NewPositionX;
							Balls[i].Position.Y = NewPositionY;
						}
						else {
							Balls[i].Live = false;
						}
					}

					// make sure at least one ball is in play
					if(Balls[0].BallCount < 1) {
						game_over = true;
					}
					}
                }
                else {
                    // end game animation logic
                }
                // trigger a render every tick
				redraw = true;
            }
            else if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) {
                break;
            }
            else if(ev.type == ALLEGRO_EVENT_MOUSE_AXES || ev.type == ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY) {
                if(!game_over) {
                    // update each paddle
					for(int i = 0; i < Paddles.size(); i++) {
						// horizontal clip
						if(Paddles[i].IsHorizontal()) {
							if(ev.mouse.x < (Paddles[i].Width / 2) ) {
								Paddles[i].Position.X = 0;
							}
							else if(ev.mouse.x > DisplayWidth - (Paddles[i].Width / 2) ) {
								Paddles[i].Position.X = DisplayWidth - Paddles[i].Width;
							}
							else {
								Paddles[i].Position.X = ev.mouse.x - (Paddles[i].Width / 2);
							}
						}
						else {
						// vertical clip
							if(ev.mouse.y < (Paddles[i].Height / 2) ) {
								Paddles[i].Position.Y = 0;
							}
							else if(ev.mouse.y > DisplayHeight - (Paddles[i].Height / 2) ) {
								Paddles[i].Position.Y = DisplayHeight - Paddles[i].Height;
							}
							else {
								Paddles[i].Position.Y = ev.mouse.y - (Paddles[i].Height / 2);
							}
						}
					}
                }
                else {
                    // track mouse movement for retry menu logic
                }
            }
            else if(ev.type == ALLEGRO_EVENT_MOUSE_BUTTON_UP) {
                if(game_over) {
                    // track mouse clicks for retry menu logic
                }
				else {
					// Debug
					// add a ball at the current mouse position
				}
            }
            else if(ev.type == ALLEGRO_EVENT_KEY_DOWN) {
                // set keys we are interested in if pressed
                switch(ev.keyboard.keycode) {
                    case ALLEGRO_KEY_ESCAPE:
                        key[KEY_ESC] = true;
                        break;
					case ALLEGRO_KEY_SPACE:
                        key[KEY_SPACE] = true;
                        break;
                }
            }
            else if(ev.type == ALLEGRO_EVENT_KEY_UP) {
                // release keys we are interested in if let go
                switch(ev.keyboard.keycode) {
                    case ALLEGRO_KEY_ESCAPE:
                        key[KEY_ESC] = false;
                        break;
					case ALLEGRO_KEY_SPACE:
                        key[KEY_SPACE] = false;
                        break;
                }
            }

            if(redraw && al_is_event_queue_empty(EventQueue)) {
                //The render loop
                redraw = false;
                if(!game_over) {
					// game play
                    // blank
                    al_clear_to_color(al_map_rgb(128,128,128));
                    
					// render each brick
					for(int i = 0; i < Bricks.size(); i++)
					{
						Bricks[i].Render();
					}

					// render each ball
					for(int i = 0; i < Balls.size(); i++)
					{
						Balls[i].Render();
					}

					// render each paddle
					for(int i = 0; i < Paddles.size(); i++)
					{
						Paddles[i].Render();
					}
					
					// render HUD
					sprintf (scoretxt, "%d", score);
					sprintf (multitxt, "%d", multi);
                    al_draw_text(Font.Medium, al_map_rgb(0,0,0), 8, 8, ALLEGRO_ALIGN_LEFT, "Score");
                    al_draw_text(Font.Medium, al_map_rgb(255,255,255), 128, 8, ALLEGRO_ALIGN_LEFT, scoretxt);
                    al_draw_text(Font.Medium, al_map_rgb(0,0,0), 300, 8, ALLEGRO_ALIGN_LEFT, "x");
                    al_draw_text(Font.Medium, al_map_rgb(255,255,255), 316, 8, ALLEGRO_ALIGN_LEFT, multitxt);
                    al_draw_text(Font.Medium, al_map_rgb(0,0,0), 424, 8, ALLEGRO_ALIGN_LEFT, hightxt);
                }
                else {
					// render retry menu
                    al_clear_to_color(al_map_rgb(128,128,128));
                }
                // always flip Display
                al_flip_display();
            }
        }
    }
    // save high score if the final score is higher
    if(final_score > high_score) {
        high_score = final_score;
    }
    sprintf (hightxt, "%d", high_score);
    // write highscore to file
    UserDataFile = al_fopen("assets/hiscore.txt", "w");
    if(UserDataFile) {
        al_fputs(UserDataFile, hightxt);
        al_fclose(UserDataFile);
    }

	// proper cleanup is important!
    al_destroy_bitmap(Bitmap.Title);
    al_destroy_bitmap(Bitmap.Logo);
    al_destroy_timer(Timer);
    al_destroy_display(Display);
    al_destroy_event_queue(EventQueue);
}
Exemplo n.º 4
0
void load(std::vector<Bone> &bones, int bmp_w, int bmp_h, std::string filename)
{
	ALLEGRO_FILE *f;
	if (engine) {
		f = engine->get_cpa()->load(filename);
	}
	else {
		f = al_fopen(filename.c_str(), "rb");
	}

	if (!f) {
		General::log_message("Error loading bones " + filename);
		return;
	}

	char buf[1000];
	while (1) {
		if (al_fgets(f, buf, 1000) == NULL)
			break;
		Bones::Type bone_type;
		sscanf(buf, "<%d>", (int *)&bone_type);
		if (al_fgets(f, buf, 1000) == NULL)
			break;
	
		std::vector<float> vertices;

		while (1) {
			int x, y, n1, n2;
			if (al_fgets(f, buf, 1000) == NULL)
				break;
			if (sscanf(buf, "\t<%d><x>%d</x><y>%d</y></%d>", &n1, &x, &y, &n2) < 4)
				break;

			vertices.push_back(x);
			vertices.push_back(y);
		}
		
		std::vector<int> splits;
		splits.push_back(vertices.size() / 2);
		float *verts = new float[vertices.size()];
		std::vector< General::Point<float> > outline;

		for (unsigned int i = 0; i < vertices.size() / 2; i++) {
			int index = i*2;
			verts[index] = vertices[index] - bmp_w/2;
			verts[index+1] = vertices[index+1] - bmp_h;
			outline.push_back(General::Point<float>(
				verts[index], verts[index+1]
			));
		}

		std::vector<Triangulate::Triangle> triangles;

		Triangulate::get_triangles(outline, splits, triangles);

		Bone b = Bone(bone_type, outline, triangles, General::Size<int>(bmp_w, bmp_h));
		bones.push_back(b);

		delete[] verts;
	}

	al_fclose(f);
}
/* get_xdg_path - locate an XDG user dir
 */
static ALLEGRO_PATH *_get_xdg_path(const char *location)
{
   ALLEGRO_PATH *location_path = NULL;
   ALLEGRO_PATH *xdg_config_path = NULL;
   ALLEGRO_FILE *xdg_config_file = NULL;   
   const char *xdg_config_home = getenv("XDG_CONFIG_HOME");
   int fd;

   if (xdg_config_home) {
      /* use $XDG_CONFIG_HOME since it exists */
      xdg_config_path = al_create_path_for_directory(xdg_config_home);
   }
   else {
      /* the default XDG location is ~/.config */
      xdg_config_path = al_get_standard_path(ALLEGRO_USER_HOME_PATH);
      if (!xdg_config_path) return NULL;      
      al_append_path_component(xdg_config_path, ".config");
   }   
   
   al_set_path_filename(xdg_config_path, "user-dirs.dirs");
   fd = open(al_path_cstr(xdg_config_path, '/'), O_RDONLY);
   if (fd != -1) {
     xdg_config_file = al_fopen_fd(fd, "r");
   }
   al_destroy_path(xdg_config_path);
   
   if (!xdg_config_file) return NULL;
      
   while (!al_feof(xdg_config_file)) {
      char line[XDG_MAX_PATH_LEN];      /* one line of the config file */
      const char *p = line;             /* where we're at in the line */
      char component[XDG_MAX_PATH_LEN]; /* the path component being parsed */      
      int i = 0;                        /* how long the current component is */

      al_fgets(xdg_config_file, line, XDG_MAX_PATH_LEN);
      
      /* skip leading white space */
      while (*p == ' ' || *p == '\t') p++;
   
      /* skip the line if it does not begin with XDG_location_DIR */            
      if (strncmp(p, "XDG_", 4)) continue;
      p += 4;
      
      if (strncmp(p, location, strlen(location))) continue;
      p += strlen(location);
      
      if (strncmp(p, "_DIR", 4)) continue;
      p += 4;
      
      /* skip past the =", allowing for white space */
      while (*p == ' ' || *p == '\t') p++;      
      if (*p++ != '=') continue;
      while (*p == ' ' || *p == '\t') p++;
      if (*p++ != '"') continue;
      
      /* We've found the right line. Now parse it, basically assuming
         that it is in a sane format. 
       */
      if (!strncmp(p, "$HOME", 5)) {
         /* $HOME is the only environment variable that the path is 
            allowed to use, and it must be first, by specification. */
         location_path = al_get_standard_path(ALLEGRO_USER_HOME_PATH);
         p += 5;
      }
      else {
         location_path = al_create_path("/");
      }
      
      while (*p) {
         if (*p == '"' || *p == '/') {
            /* add the component (if non-empty) to the path */
            if (i > 0) {
               component[i] = 0;
               al_append_path_component(location_path, component);
               i = 0;
            }
            if (*p == '"') break;
         }
         else {
            if (*p == '\\') {
               /* treat any escaped character as a literal */
               p++;
               if (!*p) break;
            }            
            component[i++] = *p;
         }
         
         p++;
      }
      
      /* Finished parsing the path. */
      break;
   }
   
   al_fclose(xdg_config_file);
   
   return location_path;
}
Exemplo n.º 6
0
void WorldStage::LoadMapFromFileOrCreateNewMap()
{
	const int MAP_WIDTH = 80;
	const int MAP_HEIGHT = 80;
	const int ARBITRARY_NUMBER_OF_WALLS = 20;
	const int VALID_VERSION = 0;
	currentMap = new RegionalMap();
	currentMap->InitToField(MAP_WIDTH, MAP_HEIGHT, 0);

	//Determine map player is on
	int mapX = 0, mapY = 0;
	auto player = actorList.GetActor(1);
	if(player)
	{
		mapX = player->x/MAP_WIDTH;
		mapY = player->y/MAP_HEIGHT;
	}

	//Load that one
	std::stringstream ss;
	ss << "region." << mapX << "." << mapY;
	
	//Try to load the region by that name
	ALLEGRO_FILE *file = al_fopen(ss.str().c_str(), "r");
	if(file)
	{
		const int BUF_SIZE = 512;
		char buffer[BUF_SIZE];
		bool isValid = true;

		if(!al_fgets(file, buffer, BUF_SIZE))
		{
			std::string str = buffer;
			if(!str.empty() && str[str.length()-1] == '\n') str.erase(str.length()-1);
			if(strcmp(str.c_str(), "b272bda9bf0c1cdcba614b5ed99c4d62") != 0)
			{
				isValid = false;
			}
		}
		if(isValid && !al_fgets(file, buffer, BUF_SIZE))
		{
			std::string str = buffer;
			if(!str.empty() && str[str.length()-1] == '\n') str.erase(str.length()-1);
			if(strcmp(str.c_str(), "0") != 0)
			{
				isValid = false;
			}
		}

		if(isValid)
		{

			for(int y = 0; y < MAP_HEIGHT; y++) for(int x = 0; x < MAP_WIDTH; x++)
			{
				//returns bytes read, 32bits = 4 bytes
				int material = al_fread32le(file);
				if(!al_feof(file))
				{
					currentMap->tile[x][y].materialTypeIndex = material;
				}
			}

			//Get actor IDs
			int actorId = al_fread32le(file);
			while(!al_feof(file))
			{
				currentMap->actorIDs.push_back(actorId);
				actorId = al_fread32le(file);
			}
		}
		al_fclose(file);
	}
	else //no file
	{
		for(int nWalls = 0; nWalls < ARBITRARY_NUMBER_OF_WALLS; nWalls++)
		{
			//Manually place down some walls to run into
			int x = rng::Rand(MAP_WIDTH);
			int y = rng::Rand(MAP_HEIGHT);
			currentMap->tile[x][y].materialTypeIndex = 1;
		}
	}


}