From e5dda46b312f13d7ee555bd2bb53995c67484123 Mon Sep 17 00:00:00 2001
From: Sebastian Krzyszkowiak <dos@dosowisko.net>
Date: Wed, 29 Feb 2012 23:00:59 +0100
Subject: [PATCH] memory bitmaps, linear filtering, menu stopping instead of
 unloading and other stuff...

---
 src/about.c   |  2 +-
 src/level.c   |  6 +++---
 src/loading.c | 35 ++++++++++++++++++++++++++++++++---
 src/main.c    | 21 ++++++++++++++++++---
 src/main.h    |  4 ++++
 src/map.c     |  2 +-
 src/menu.c    | 46 +++++++++++++++++++++++++++++++++-------------
 src/menu.h    |  1 +
 8 files changed, 93 insertions(+), 24 deletions(-)

diff --git a/src/about.c b/src/about.c
index a907bfe..5f31f9d 100644
--- a/src/about.c
+++ b/src/about.c
@@ -36,8 +36,8 @@ void About_Load(struct Game *game) {
 int About_Keydown(struct Game *game, ALLEGRO_EVENT *ev) {
 	if (ev->keyboard.keycode == ALLEGRO_KEY_ESCAPE) {
 		UnloadGameState(game);
-		game->gamestate = GAMESTATE_LOADING;
 		game->loadstate = GAMESTATE_MENU;
+		LoadGameState(game);
 	}
 	return 0;
 }
diff --git a/src/level.c b/src/level.c
index a13363c..b32e308 100644
--- a/src/level.c
+++ b/src/level.c
@@ -16,8 +16,8 @@ void Level_Draw(struct Game *game) {
 
 	game->level.derpy_pos=game->level.derpy_pos+0.00092;
 	if (game->level.derpy_pos>1) { UnloadGameState(game);
-		game->gamestate = GAMESTATE_LOADING;
-		game->loadstate = GAMESTATE_MENU; return; }
+		game->loadstate = GAMESTATE_MENU;
+		LoadGameState(game); return; }
 	game->level.derpy_frame_tmp++;
 	if (game->level.derpy_frame_tmp%3==0) {
 		if (game->level.derpy_frame_tmp%5==0) game->level.derpy_frame++;
@@ -47,8 +47,8 @@ void Level_Load(struct Game *game) {
 int Level_Keydown(struct Game *game, ALLEGRO_EVENT *ev) {
 	if (ev->keyboard.keycode == ALLEGRO_KEY_ESCAPE) {
 		UnloadGameState(game);
-		game->gamestate = GAMESTATE_LOADING;
 		game->loadstate = GAMESTATE_MENU;
+		LoadGameState(game);
 	}
 	return 0;
 }
diff --git a/src/loading.c b/src/loading.c
index 71f6fba..13f3d9e 100644
--- a/src/loading.c
+++ b/src/loading.c
@@ -36,12 +36,41 @@ void Loading_Draw(struct Game *game) {
 }
 
 void Loading_Load(struct Game *game) {
-	game->loading.image = al_load_bitmap( "data/loading.png" );
+	al_clear_to_color(al_map_rgb(0,0,0));
+	al_draw_text_with_shadow(game->font, al_map_rgb(255,255,255), al_get_display_width(game->display)*0.0234, al_get_display_height(game->display)*0.85, ALLEGRO_ALIGN_LEFT, "Loading...");
+	DrawConsole(game);
+	al_flip_display();
+
+	al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP);
+	game->loading.image = al_load_bitmap( "data/loading.png" );
+	al_set_new_bitmap_flags(ALLEGRO_MAG_LINEAR | ALLEGRO_MIN_LINEAR);
 
-	// Scale "Loading" bitmap
 	game->loading.loading_bitmap = al_create_bitmap(al_get_display_width(game->display), al_get_display_height(game->display));
 	al_set_target_bitmap(game->loading.loading_bitmap);
-	al_draw_scaled_bitmap(game->loading.image,0, 0, al_get_bitmap_width(game->loading.image), al_get_bitmap_height(game->loading.image), 0, 0, al_get_display_width(game->display), al_get_display_height(game->display),0);
+
+	int width = al_get_display_width(game->display);
+	int height = al_get_display_height(game->display);
+	int x, y;
+	for (y = 0; y < height; y++) {
+		float pixy = ((float)y / height) * al_get_bitmap_height(game->loading.image);
+		for (x = 0; x < width; x++) {
+			float pixx = ((float)x / width) * al_get_bitmap_width(game->loading.image);
+			ALLEGRO_COLOR a = al_get_pixel(game->loading.image, pixx-0.25, pixy-0.25);
+			ALLEGRO_COLOR b = al_get_pixel(game->loading.image, pixx+0.25, pixy-0.25);
+			ALLEGRO_COLOR c = al_get_pixel(game->loading.image, pixx-0.25, pixy+0.25);
+			ALLEGRO_COLOR d = al_get_pixel(game->loading.image, pixx+0.25, pixy+0.25);
+			ALLEGRO_COLOR result = al_map_rgba_f(
+				(a.r+b.r+c.r+d.r) / 4,
+				(a.g+b.b+c.g+d.g) / 4,
+				(a.b+b.g+c.b+d.b) / 4,
+				(a.a+b.a+c.a+d.a) / 4
+			);
+			al_put_pixel(x, y, result);
+		}
+	}
+
+	// Scale "Loading" bitmap
+	//al_draw_scaled_bitmap(game->loading.image,0, 0, al_get_bitmap_width(game->loading.image), al_get_bitmap_height(game->loading.image), 0, 0, al_get_display_width(game->display), al_get_display_height(game->display),0);
 	al_draw_text_with_shadow(game->font, al_map_rgb(255,255,255), al_get_display_width(game->display)*0.0234, al_get_display_height(game->display)*0.85, ALLEGRO_ALIGN_LEFT, "Loading...");
 	al_set_target_bitmap(al_get_backbuffer(game->display));
 	al_destroy_bitmap(game->loading.image);
diff --git a/src/main.c b/src/main.c
index f01b40e..3420da6 100644
--- a/src/main.c
+++ b/src/main.c
@@ -67,6 +67,10 @@ void DrawConsole(struct Game *game) {
 }
 
 void PreloadGameState(struct Game *game) {
+	if ((game->loadstate==GAMESTATE_MENU) && (game->menu.loaded)) {
+		PrintConsole(game, "GAMESTATE_MENU already loaded, skipping...");
+		return;
+	}
 	switch (game->loadstate) {
 		PRELOAD_STATE(GAMESTATE_MENU, Menu)
 		PRELOAD_STATE(GAMESTATE_LOADING, Loading)
@@ -83,7 +87,13 @@ void PreloadGameState(struct Game *game) {
 
 void UnloadGameState(struct Game *game) {
 	switch (game->gamestate) {
-		UNLOAD_STATE(GAMESTATE_MENU, Menu)
+		case GAMESTATE_MENU:
+			if (game->shuttingdown) { 
+				PrintConsole(game, "Unload GAMESTATE_MENU..."); Menu_Unload(game);
+			} else {
+				PrintConsole(game, "Just stopping GAMESTATE_MENU..."); Menu_Stop(game);
+			}
+			break;
 		UNLOAD_STATE(GAMESTATE_LOADING, Loading)
 		UNLOAD_STATE(GAMESTATE_ABOUT, About)
 		UNLOAD_STATE(GAMESTATE_INTRO, Intro)
@@ -136,8 +146,6 @@ int main(int argc, char **argv){
 		fprintf(stderr, "failed to initialize allegro!\n");
 		return -1;
 	}
-
-	al_set_new_bitmap_flags(ALLEGRO_MIN_LINEAR^ALLEGRO_MAG_LINEAR);
    
 	game.timer = al_create_timer(ALLEGRO_BPS_TO_SECS(game.fps));
 	if(!game.timer) {
@@ -181,6 +189,7 @@ int main(int argc, char **argv){
 
 	if (game.fullscreen) al_set_new_display_flags(ALLEGRO_FULLSCREEN_WINDOW);
 	al_set_new_display_option(ALLEGRO_VSYNC, 1, ALLEGRO_SUGGEST);
+	al_set_new_display_option(ALLEGRO_OPENGL, 1, ALLEGRO_SUGGEST);
 	game.display = al_create_display(game.width, game.height);
 	if(!game.display) {
 		fprintf(stderr, "failed to create display!\n");
@@ -188,6 +197,9 @@ int main(int argc, char **argv){
 	}
 	al_set_window_title(game.display, "Super Derpy: Muffin Attack");
 	if (game.fullscreen) al_hide_mouse_cursor(game.display);
+
+	al_set_new_bitmap_flags(ALLEGRO_MAG_LINEAR | ALLEGRO_MIN_LINEAR);
+
 	game.font = al_load_ttf_font("data/ShadowsIntoLight.ttf",al_get_display_height(game.display)*0.09,0 );
 	game.font_console = al_load_ttf_font("data/DejaVuSansMono.ttf",al_get_display_height(game.display)*0.018,0 );
    
@@ -213,6 +225,8 @@ int main(int argc, char **argv){
 
 	al_start_timer(game.timer);
 
+	game.shuttingdown = false;
+	game.menu.loaded = false;
 	game.loadstate = GAMESTATE_LOADING;
 	PreloadGameState(&game);
 	LoadGameState(&game);
@@ -273,6 +287,7 @@ int main(int argc, char **argv){
 			al_flip_display();
 		}
 	}
+	game.shuttingdown = true;
 	UnloadGameState(&game);
 	if (game.gamestate != GAMESTATE_LOADING) {
 		game.gamestate = GAMESTATE_LOADING;
diff --git a/src/main.h b/src/main.h
index 55ccb2a..29d667e 100644
--- a/src/main.h
+++ b/src/main.h
@@ -50,8 +50,10 @@ struct Menu {
 	ALLEGRO_BITMAP *pie;
 	ALLEGRO_BITMAP *pie_bitmap;
 	ALLEGRO_BITMAP *pinkcloud_bitmap;
+	ALLEGRO_BITMAP *pinkcloud_scaled;
 	ALLEGRO_BITMAP *pinkcloud;
 	ALLEGRO_BITMAP *rain;
+	ALLEGRO_BITMAP *rain_bitmap;
 	ALLEGRO_BITMAP *mountain_bitmap;
 	ALLEGRO_BITMAP *mountain;
 	float cloud_position;
@@ -67,6 +69,7 @@ struct Menu {
 	int selected;
 	bool options;
 	bool draw_while_fading;
+	bool loaded;
 };
 
 /*! \brief Resources used by Loading state. */
@@ -129,6 +132,7 @@ struct Game {
 	int fps;
 	int width;
 	int height;
+	bool shuttingdown;
 	struct Menu menu;
 	struct Loading loading;
 	struct Intro intro;
diff --git a/src/map.c b/src/map.c
index ec54646..cc9331c 100644
--- a/src/map.c
+++ b/src/map.c
@@ -71,8 +71,8 @@ int Map_Keydown(struct Game *game, ALLEGRO_EVENT *ev) {
 		return 0;
 	} else if (ev->keyboard.keycode == ALLEGRO_KEY_ESCAPE) {
 		UnloadGameState(game);
-		game->gamestate = GAMESTATE_LOADING;
 		game->loadstate = GAMESTATE_MENU;
+		LoadGameState(game);
 		return 0;
 	} else { return 0; }
 	if (game->map.selected<1) game->map.selected=1;
diff --git a/src/menu.c b/src/menu.c
index c3e38ca..045b977 100644
--- a/src/menu.c
+++ b/src/menu.c
@@ -15,11 +15,11 @@ void Menu_Draw(struct Game *game) {
 	float x = 1.5;//*(rand() / (float)RAND_MAX);
 	int minus;
 	if (game->menu.cloud_position>0) minus=1; else minus=-1;
-	al_draw_scaled_bitmap(game->menu.rain, 0, 0, al_get_bitmap_width(game->menu.rain), al_get_bitmap_height(game->menu.rain), fmod(minus*game->menu.cloud_position,3)*x*5+al_get_bitmap_width(game->menu.pinkcloud_bitmap)/2.7, al_get_bitmap_height(game->menu.pinkcloud_bitmap)*(0.88+(fmod(-1.8*(game->menu.cloud_position+80), 6))/20.0), al_get_bitmap_width(game->menu.pinkcloud_bitmap)*0.5, al_get_bitmap_height(game->menu.pinkcloud_bitmap)*0.1, 0);
-	al_draw_scaled_bitmap(game->menu.rain, 0, 0, al_get_bitmap_width(game->menu.rain), al_get_bitmap_height(game->menu.rain), fmod(minus*game->menu.cloud_position,3)*x*3+al_get_bitmap_width(game->menu.pinkcloud_bitmap)/3.1, al_get_bitmap_height(game->menu.pinkcloud_bitmap)*(0.78+(fmod(-2.8*(game->menu.cloud_position+80), 4))/18.0), al_get_bitmap_width(game->menu.pinkcloud_bitmap)*0.5, al_get_bitmap_height(game->menu.pinkcloud_bitmap)*0.1, 0);
-	al_draw_scaled_bitmap(game->menu.rain, 0, 0, al_get_bitmap_width(game->menu.rain), al_get_bitmap_height(game->menu.rain), fmod(minus*game->menu.cloud_position,3)*x*6+al_get_bitmap_width(game->menu.pinkcloud_bitmap)/2.1, al_get_bitmap_height(game->menu.pinkcloud_bitmap)*(0.87+(fmod(-4.9*(game->menu.cloud_position+80), 8))/26.0), al_get_bitmap_width(game->menu.pinkcloud_bitmap)*0.4, al_get_bitmap_height(game->menu.pinkcloud_bitmap)*0.08, 0);
+	al_draw_bitmap(game->menu.rain_bitmap, fmod(minus*game->menu.cloud_position,3)*x*5+al_get_bitmap_width(game->menu.pinkcloud_bitmap)/2.7, al_get_bitmap_height(game->menu.pinkcloud_bitmap)*(0.88+(fmod(-1.8*(game->menu.cloud_position+80), 6))/20.0), 0);
+	al_draw_bitmap(game->menu.rain_bitmap, fmod(minus*game->menu.cloud_position,3)*x*3+al_get_bitmap_width(game->menu.pinkcloud_bitmap)/3.1, al_get_bitmap_height(game->menu.pinkcloud_bitmap)*(0.78+(fmod(-2.8*(game->menu.cloud_position+80), 4))/18.0), 0);
+	al_draw_scaled_bitmap(game->menu.rain_bitmap, 0, 0, al_get_bitmap_width(game->menu.rain_bitmap), al_get_bitmap_height(game->menu.rain_bitmap), fmod(minus*game->menu.cloud_position,3)*x*6+al_get_bitmap_width(game->menu.pinkcloud_bitmap)/2.1, al_get_bitmap_height(game->menu.pinkcloud_bitmap)*(0.87+(fmod(-4.9*(game->menu.cloud_position+80), 8))/26.0), al_get_bitmap_width(game->menu.pinkcloud_bitmap)*0.4, al_get_bitmap_height(game->menu.pinkcloud_bitmap)*0.08, 0);
 	//al_draw_scaled_bitmap(game->menu.rain, 0, 0, al_get_bitmap_width(game->menu.rain), al_get_bitmap_height(game->menu.rain), fmod(minus*game->menu.cloud_position,3)*x*6+al_get_bitmap_width(game->menu.pinkcloud_bitmap)/2.4, al_get_bitmap_height(game->menu.pinkcloud_bitmap)*(0.9+(fmod(-5*(game->menu.cloud_position+86), 8))/20.0), al_get_bitmap_width(game->menu.pinkcloud_bitmap)*0.35, al_get_bitmap_height(game->menu.pinkcloud_bitmap)*0.07, 0);
-	al_draw_scaled_bitmap(game->menu.pinkcloud,0, 0, al_get_bitmap_width(game->menu.pinkcloud), al_get_bitmap_height(game->menu.pinkcloud), 0, 0, al_get_bitmap_width(game->menu.pinkcloud_bitmap), al_get_bitmap_height(game->menu.pinkcloud_bitmap)*0.8122,0);
+	al_draw_bitmap(game->menu.pinkcloud_scaled, 0, 0, 0);
 	al_set_target_bitmap(al_get_backbuffer(game->display));
 
 	al_clear_to_color(al_map_rgb(183,234,193));
@@ -68,22 +68,26 @@ void Menu_Draw(struct Game *game) {
 }
 
 void Menu_Preload(struct Game *game) {
+	game->menu.loaded = true;
 	game->menu.draw_while_fading = atoi(GetConfigOptionDefault("[MuffinAttack]", "menu_draw_while_fading", "1"));
 	game->menu.cloud_position = 100;
 	game->menu.cloud2_position = 100;
 	game->menu.options = false;
 	//game->menu.image = al_create_bitmap(al_get_display_width(game->display), al_get_display_height(game->display));
 	//al_destroy_bitmap(game->menu.image); // ugh...
+	al_set_new_bitmap_flags(ALLEGRO_MAG_LINEAR | ALLEGRO_MEMORY_BITMAP);
 	game->menu.image = al_load_bitmap( "data/menu.png" );
 	game->menu.mountain = al_load_bitmap( "data/mountain.png" );
+	game->menu.cloud = al_load_bitmap( "data/cloud.png" );
+	game->menu.cloud2 = al_load_bitmap( "data/cloud2.png" );
+	game->menu.rain = al_load_bitmap( "data/rain.png" );
+	game->menu.pie = al_load_bitmap( "data/pie.png" );
+	game->menu.pinkcloud = al_load_bitmap( "data/pinkcloud.png" );
+	al_set_new_bitmap_flags(ALLEGRO_MAG_LINEAR);
+
 	game->menu.sample = al_load_sample( "data/menu.flac" );
 	game->menu.rain_sample = al_load_sample( "data/rain.flac" );
 	game->menu.click_sample = al_load_sample( "data/click.flac" );
-	game->menu.cloud = al_load_bitmap( "data/cloud.png" );
-	game->menu.cloud2 = al_load_bitmap( "data/cloud2.png" );
-	game->menu.pinkcloud = al_load_bitmap( "data/pinkcloud.png" );
-	game->menu.pie = al_load_bitmap( "data/pie.png" );
-	game->menu.rain = al_load_bitmap( "data/rain.png" );
 	game->menu.mountain_position = al_get_display_width(game->display)*0.7;
 
 	game->menu.font_title = al_load_ttf_font("data/ShadowsIntoLight.ttf",al_get_display_height(game->display)*0.16,0 );
@@ -127,6 +131,10 @@ void Menu_Preload(struct Game *game) {
 	al_destroy_bitmap(game->menu.cloud2);
 	
 	game->menu.pinkcloud_bitmap = al_create_bitmap(al_get_display_width(game->display)*0.33125, al_get_display_height(game->display)); //*0.8122);
+	game->menu.pinkcloud_scaled = al_create_bitmap(al_get_bitmap_width(game->menu.pinkcloud_bitmap), al_get_bitmap_height(game->menu.pinkcloud_bitmap)*0.8122);
+	al_set_target_bitmap(game->menu.pinkcloud_scaled);
+	al_draw_scaled_bitmap(game->menu.pinkcloud,0, 0, al_get_bitmap_width(game->menu.pinkcloud), al_get_bitmap_height(game->menu.pinkcloud), 0, 0, al_get_bitmap_width(game->menu.pinkcloud_scaled), al_get_bitmap_height(game->menu.pinkcloud_scaled),0);
+	al_destroy_bitmap(game->menu.pinkcloud);
 
 	game->menu.pie_bitmap = al_create_bitmap(al_get_display_width(game->display)/2, al_get_display_height(game->display)); //*0.8122);
 	al_set_target_bitmap(game->menu.pie_bitmap);
@@ -142,11 +150,18 @@ void Menu_Preload(struct Game *game) {
 	al_draw_scaled_bitmap(game->menu.mountain,0, 0, al_get_bitmap_width(game->menu.mountain), al_get_bitmap_height(game->menu.mountain), 0, 0, al_get_bitmap_width(game->menu.mountain_bitmap), al_get_bitmap_height(game->menu.mountain_bitmap),0);
 	al_destroy_bitmap(game->menu.mountain);
 
+	al_set_new_bitmap_flags(ALLEGRO_VIDEO_BITMAP);
+	game->menu.rain_bitmap = al_create_bitmap(al_get_bitmap_width(game->menu.pinkcloud_bitmap)*0.5, al_get_bitmap_height(game->menu.pinkcloud_bitmap)*0.1);
+	al_set_new_bitmap_flags(ALLEGRO_MIN_LINEAR | ALLEGRO_MAG_LINEAR);
+	al_set_target_bitmap(game->menu.rain_bitmap);
+	al_clear_to_color(al_map_rgba(0,0,0,0));
+	al_draw_scaled_bitmap(game->menu.rain,0, 0, al_get_bitmap_width(game->menu.rain), al_get_bitmap_height(game->menu.rain), 0, 0, al_get_bitmap_width(game->menu.rain_bitmap), al_get_bitmap_height(game->menu.rain_bitmap),0);
+	al_destroy_bitmap(game->menu.rain);
+
 	game->menu.selected = 0;
 }
 
-void Menu_Unload(struct Game *game) {
-
+void Menu_Stop(struct Game* game) {
 	game->menu.menu_fade_bitmap = al_create_bitmap(al_get_display_width(game->display), al_get_display_height(game->display));
 
 	ALLEGRO_EVENT ev;
@@ -163,13 +178,18 @@ void Menu_Unload(struct Game *game) {
 		DrawConsole(game);
 		al_flip_display();
 	}
+	al_stop_samples();
+}
+
+void Menu_Unload(struct Game *game) {
+	Menu_Stop(game);
 	al_destroy_bitmap(game->menu.menu_fade_bitmap);
-	al_destroy_bitmap(game->menu.pinkcloud);
+	al_destroy_bitmap(game->menu.pinkcloud_scaled);
 	al_destroy_bitmap(game->menu.menu_bitmap);
 	al_destroy_bitmap(game->menu.cloud_bitmap);
 	al_destroy_bitmap(game->menu.cloud2_bitmap);
 	al_destroy_bitmap(game->menu.pinkcloud_bitmap);
-	al_destroy_bitmap(game->menu.rain);
+	al_destroy_bitmap(game->menu.rain_bitmap);
 	al_destroy_bitmap(game->menu.mountain_bitmap);
 	al_destroy_bitmap(game->menu.pie_bitmap);
 	al_destroy_font(game->menu.font_title);
diff --git a/src/menu.h b/src/menu.h
index 1d1fa83..8ee5736 100644
--- a/src/menu.h
+++ b/src/menu.h
@@ -6,6 +6,7 @@
 
 void Menu_Draw(struct Game *game);
 void Menu_Preload(struct Game *game);
+void Menu_Stop(struct Game *game);
 void Menu_Unload(struct Game *game);
 void Menu_Load(struct Game *game);
 int Menu_Keydown(struct Game *game, ALLEGRO_EVENT *ev);