shithub: cstory

Download patch

ref: 0eaca9966c1af506719ec94f0daad24782966dab
parent: a8c4955b75a16fae40fe051b942cf9816ce3b358
author: Clownacy <[email protected]>
date: Mon May 6 12:49:52 EDT 2019

Made Bullet.cpp ASM-accurate

--- a/msvc2003/devilution/comparer-config.toml
+++ b/msvc2003/devilution/comparer-config.toml
@@ -60,6 +60,134 @@
 addr = 0x403740
 
 [[func]]
+name = "InitBullet"
+addr = 0x403C00
+
+[[func]]
+name = "CountArmsBullet"
+addr = 0x403C40
+
+[[func]]
+name = "CountBulletNum"
+addr = 0x403CB0
+
+[[func]]
+name = "DeleteBullet"
+addr = 0x403D10
+
+[[func]]
+name = "ClearBullet"
+addr = 0x403D80
+
+[[func]]
+name = "PutBullet"
+addr = 0x403DC0
+
+[[func]]
+name = "SetBullet"
+addr = 0x403F80
+
+[[func]]
+name = "ActBullet_Frontia1"
+addr = 0x404160
+
+[[func]]
+name = "ActBullet_Frontia2"
+addr = 0x4043F0
+
+[[func]]
+name = "ActBullet_PoleStar"
+addr = 0x4047B0
+
+[[func]]
+name = "ActBullet_FireBall"
+addr = 0x404B30
+
+[[func]]
+name = "ActBullet_MachineGun"
+addr = 0x405120
+
+[[func]]
+name = "ActBullet_Missile"
+addr = 0x4055A0
+
+[[func]]
+name = "ActBullet_Bom"
+addr = 0x405D80
+
+[[func]]
+name = "ActBullet_Bubblin1"
+addr = 0x405F30
+
+[[func]]
+name = "ActBullet_Bubblin2"
+addr = 0x406190
+
+[[func]]
+name = "ActBullet_Bubblin3"
+addr = 0x4064D0
+
+[[func]]
+name = "ActBullet_Spine"
+addr = 0x4068B0
+
+[[func]]
+name = "ActBullet_Sword1"
+addr = 0x406BB0
+
+[[func]]
+name = "ActBullet_Sword2"
+addr = 0x406E60
+
+[[func]]
+name = "ActBullet_Sword3"
+addr = 0x407110
+
+[[func]]
+name = "ActBullet_Edge"
+addr = 0x4075E0
+
+[[func]]
+name = "ActBullet_Drop"
+addr = 0x4078A0
+
+[[func]]
+name = "ActBullet_SuperMissile"
+addr = 0x407910
+
+[[func]]
+name = "ActBullet_SuperBom"
+addr = 0x408080
+
+[[func]]
+name = "ActBullet_Nemesis"
+addr = 0x408230
+
+[[func]]
+name = "ActBullet_Spur"
+addr = 0x408710
+
+[[func]]
+name = "ActBullet_SpurTail"
+addr = 0x408AE0
+
+[[func]]
+name = "ActBullet_EnemyClear"
+addr = 0x408F40
+
+[[func]]
+name = "ActBullet_Star"
+addr = 0x408F90
+
+[[func]]
+name = "ActBullet"
+addr = 0x408FC0
+
+[[func]]
+name = "IsActiveSomeBullet"
+addr = 0x4095C0
+
+[[func]]
 name = "Call_Escape"
 addr = 0x40DD70
 
--- a/src/Bullet.cpp
+++ b/src/Bullet.cpp
@@ -96,7 +96,9 @@
 
 void DeleteBullet(int code)
 {
-	for (int i = 0; i < BULLET_MAX; i++)
+	int i;
+	int unknown = 0;	// Not the original name
+	for (i = 0; i < BULLET_MAX; i++)
 	{
 		if (gBul[i].cond & 0x80)
 		{
@@ -114,12 +116,13 @@
 
 void PutBullet(int fx, int fy)
 {
-	for (int i = 0; i < BULLET_MAX; i++)
+	int i;
+	int x, y;
+
+	for (i = 0; i < BULLET_MAX; i++)
 	{
 		if (gBul[i].cond & 0x80)
-		{
-			int x, y;
-			
+		{			
 			switch (gBul[i].direct)
 			{
 				case 0:
@@ -147,31 +150,31 @@
 
 void SetBullet(int no, int x, int y, int dir)
 {
-	for (int i = 0; i < BULLET_MAX; i++)
-	{
-		if (!(gBul[i].cond & 0x80))
-		{
-			memset(&gBul[i], 0, sizeof(BULLET));
-			gBul[i].code_bullet = no;
-			gBul[i].cond = 0x80;
-			gBul[i].direct = dir;
-			gBul[i].damage = gBulTbl[no].damage;
-			gBul[i].life = gBulTbl[no].life;
-			gBul[i].life_count = gBulTbl[no].life_count;
-			gBul[i].bbits = gBulTbl[no].bbits;
-			gBul[i].enemyXL = gBulTbl[no].enemyXL << 9;
-			gBul[i].enemyYL = gBulTbl[no].enemyYL << 9;
-			gBul[i].blockXL = gBulTbl[no].blockXL << 9;
-			gBul[i].blockYL = gBulTbl[no].blockYL << 9;
-			gBul[i].view.back = gBulTbl[no].view.back << 9;
-			gBul[i].view.front = gBulTbl[no].view.front << 9;
-			gBul[i].view.top = gBulTbl[no].view.top << 9;
-			gBul[i].view.bottom = gBulTbl[no].view.bottom << 9;
-			gBul[i].x = x;
-			gBul[i].y = y;
-			break;
-		}
-	}
+	int i = 0;
+	while (i < BULLET_MAX && gBul[i].cond & 0x80)
+		++i;
+
+	if (i >= BULLET_MAX)
+		return;
+
+	memset(&gBul[i], 0, sizeof(BULLET));
+	gBul[i].code_bullet = no;
+	gBul[i].cond = 0x80;
+	gBul[i].direct = dir;
+	gBul[i].damage = gBulTbl[no].damage;
+	gBul[i].life = gBulTbl[no].life;
+	gBul[i].life_count = gBulTbl[no].life_count;
+	gBul[i].bbits = gBulTbl[no].bbits;
+	gBul[i].enemyXL = gBulTbl[no].enemyXL << 9;
+	gBul[i].enemyYL = gBulTbl[no].enemyYL << 9;
+	gBul[i].blockXL = gBulTbl[no].blockXL << 9;
+	gBul[i].blockYL = gBulTbl[no].blockYL << 9;
+	gBul[i].view.back = gBulTbl[no].view.back << 9;
+	gBul[i].view.front = gBulTbl[no].view.front << 9;
+	gBul[i].view.top = gBulTbl[no].view.top << 9;
+	gBul[i].view.bottom = gBulTbl[no].view.bottom << 9;
+	gBul[i].x = x;
+	gBul[i].y = y;
 }
 
 void ActBullet_Frontia1(BULLET *bul)
@@ -183,13 +186,8 @@
 	}
 	else
 	{
-		if (bul->act_no)
+		if (bul->act_no == 0)
 		{
-			bul->x += bul->xm;
-			bul->y += bul->ym;
-		}
-		else
-		{
 			bul->ani_no = Random(0, 2);
 			bul->act_no = 1;
 
@@ -209,6 +207,11 @@
 					break;
 			}
 		}
+		else
+		{
+			bul->x += bul->xm;
+			bul->y += bul->ym;
+		}
 
 		if (++bul->ani_wait > 0)
 		{
@@ -249,98 +252,98 @@
 	}
 	else
 	{
-		if (bul->act_no)
+		if (bul->act_no == 0)
 		{
+			bul->ani_no = Random(0, 2);
+			bul->act_no = 1;
+
 			switch (bul->direct)
 			{
 				case 0:
-					bul->xm -= 0x80;
+					bul->xm = -0x200;
 					break;
 				case 1:
-					bul->ym -= 0x80;
+					bul->ym = -0x200;
 					break;
 				case 2:
-					bul->xm += 0x80;
+					bul->xm = 0x200;
 					break;
 				case 3:
-					bul->ym += 0x80;
+					bul->ym = 0x200;
 					break;
 			}
 
+			static unsigned int inc;
+			++inc;
+
 			switch (bul->direct)
 			{
 				case 0:
 				case 2:
-					if (bul->count1 % 5 == 2)
-					{
-						if (bul->ym < 0)
-							bul->ym = 0x400;
-						else
-							bul->ym = -0x400;
-					}
+					if (inc % 2)
+						bul->ym = 0x400;
+					else
+						bul->ym = -0x400;
 
 					break;
 
-				case 1u:
-				case 3u:
-					if (bul->count1 % 5 == 2)
-					{
-						if (bul->xm < 0)
-							bul->xm = 0x400;
-						else
-							bul->xm = -0x400;
-					}
+				case 1:
+				case 3:
+					if (inc % 2)
+						bul->xm = 0x400;
+					else
+						bul->xm = -0x400;
 
 					break;
 			}
-
-			bul->x += bul->xm;
-			bul->y += bul->ym;
 		}
 		else
 		{
-			bul->ani_no = Random(0, 2);
-			bul->act_no = 1;
-
 			switch (bul->direct)
 			{
 				case 0:
-					bul->xm = -0x200;
+					bul->xm -= 0x80;
 					break;
 				case 1:
-					bul->ym = -0x200;
+					bul->ym -= 0x80;
 					break;
 				case 2:
-					bul->xm = 0x200;
+					bul->xm += 0x80;
 					break;
 				case 3:
-					bul->ym = 0x200;
+					bul->ym += 0x80;
 					break;
 			}
 
-			static unsigned int inc;
-			++inc;
-
 			switch (bul->direct)
 			{
 				case 0:
 				case 2:
-					if (inc % 2)
-						bul->ym = 0x400;
-					else
-						bul->ym = -0x400;
+					if (bul->count1 % 5 == 2)
+					{
+						if (bul->ym < 0)
+							bul->ym = 0x400;
+						else
+							bul->ym = -0x400;
+					}
 
 					break;
 
-				case 1:
-				case 3:
-					if (inc % 2)
-						bul->xm = -0x400;
-					else
-						bul->xm = 0x400;
+				case 1u:
+				case 3u:
+					if (bul->count1 % 5 == 2)
+					{
+						if (bul->xm < 0)
+							bul->xm = 0x400;
+						else
+							bul->xm = -0x400;
+					}
 
 					break;
 			}
+
+			bul->x += bul->xm;
+			bul->y += bul->ym;
 		}
 
 		if ( ++bul->ani_wait > 0 )
@@ -369,16 +372,19 @@
 
 void ActBullet_PoleStar(BULLET *bul, int level)
 {
-	if (++bul->count1 <= bul->life_count)
+	RECT rect1[2];
+	RECT rect2[2];
+	RECT rect3[2];
+
+	if (++bul->count1 > bul->life_count)
 	{
-		if (bul->act_no)
+		bul->cond = 0;
+		SetCaret(bul->x, bul->y, 3, 0);
+	}
+	else
+	{
+		if (bul->act_no == 0)
 		{
-			//Move
-			bul->x += bul->xm;
-			bul->y += bul->ym;
-		}
-		else
-		{
 			bul->act_no = 1;
 			
 			//Set speed
@@ -399,114 +405,108 @@
 			}
 			
 			//Set hitbox
-			if (level == 1)
-			{
-				switch (bul->direct)
-				{
-					case 0:
-						bul->enemyYL = 0x400;
-						break;
-					case 1:
-						bul->enemyXL = 0x400;
-						break;
-					case 2:
-						bul->enemyYL = 0x400;
-						break;
-					case 3:
-						bul->enemyXL = 0x400;
-						break;
-				}
-			}
-			else if (level == 2)
-			{
-				switch (bul->direct)
-				{
-					case 0:
-						bul->enemyYL = 0x800;
-						break;
-					case 1:
-						bul->enemyXL = 0x800;
-						break;
-					case 2:
-						bul->enemyYL = 0x800;
-						break;
-					case 3:
-						bul->enemyXL = 0x800;
-						break;
-				}
-			}
-			
-			//Set framerect
 			switch (level)
 			{
 				case 1:
-					if (bul->direct != 1 && bul->direct != 3)
+					switch (bul->direct)
 					{
-						bul->rect.left = 128;
-						bul->rect.top = 32;
-						bul->rect.right = 144;
-						bul->rect.bottom = 48;
+						case 0:
+							bul->enemyYL = 0x400;
+							break;
+						case 1:
+							bul->enemyXL = 0x400;
+							break;
+						case 2:
+							bul->enemyYL = 0x400;
+							break;
+						case 3:
+							bul->enemyXL = 0x400;
+							break;
 					}
-					else
-					{
-						bul->rect.left = 144;
-						bul->rect.top = 32;
-						bul->rect.right = 160;
-						bul->rect.bottom = 48;
-					}
 					break;
 				case 2:
-					if (bul->direct != 1 && bul->direct != 3)
+					switch (bul->direct)
 					{
-						bul->rect.left = 160;
-						bul->rect.top = 32;
-						bul->rect.right = 176;
-						bul->rect.bottom = 48;
+						case 0:
+							bul->enemyYL = 0x800;
+							break;
+						case 1:
+							bul->enemyXL = 0x800;
+							break;
+						case 2:
+							bul->enemyYL = 0x800;
+							break;
+						case 3:
+							bul->enemyXL = 0x800;
+							break;
 					}
-					else
-					{
-						bul->rect.left = 176;
-						bul->rect.top = 32;
-						bul->rect.right = 192;
-						bul->rect.bottom = 48;
-
-					}
 					break;
-				case 3:
-					if (bul->direct != 1 && bul->direct != 3)
-					{
-						bul->rect.left = 128;
-						bul->rect.top = 48;
-						bul->rect.right = 144;
-						bul->rect.bottom = 64;
-					}
-					else
-					{
-						bul->rect.left = 144;
-						bul->rect.top = 48;
-						bul->rect.right = 160;
-						bul->rect.bottom = 64;
-					}
-					break;
 			}
 		}
+		else
+		{
+			//Move
+			bul->x += bul->xm;
+			bul->y += bul->ym;
+		}
+
+		SET_RECT(rect1[0], 128, 32, 144, 48)
+		SET_RECT(rect1[1], 144, 32, 160, 48)
+
+		SET_RECT(rect2[0], 160, 32, 176, 48)
+		SET_RECT(rect2[1], 176, 32, 192, 48)
+
+		SET_RECT(rect3[0], 128, 48, 144, 64)
+		SET_RECT(rect3[1], 144, 48, 160, 64)
+
+		//Set framerect
+		switch (level)
+		{
+			case 1:
+				if (bul->direct == 1 || bul->direct == 3)
+					bul->rect = rect1[1];
+				else
+					bul->rect = rect1[0];
+
+				break;
+			case 2:
+				if (bul->direct == 1 || bul->direct == 3)
+					bul->rect = rect2[1];
+				else
+					bul->rect = rect2[0];
+
+				break;
+			case 3:
+				if (bul->direct == 1 || bul->direct == 3)
+					bul->rect = rect3[1];
+				else
+					bul->rect = rect3[0];
+
+				break;
+		}
 	}
-	else
-	{
-		bul->cond = 0;
-		SetCaret(bul->x, bul->y, 3, 0);
-	}
 }
 
 void ActBullet_FireBall(BULLET *bul, int level)
 {
-	if (++bul->count1 <= bul->life_count)
+	BOOL bBreak;
+	RECT rect_left1[4];
+	RECT rect_right1[4];
+	RECT rect_left2[3];
+	RECT rect_right2[3];
+
+	if (++bul->count1 > bul->life_count)
 	{
-		bool bBreak = false;
+		bul->cond = 0;
+		SetCaret(bul->x, bul->y, 3, 0);
+	}
+	else
+	{
+		bBreak = FALSE;
 		if (bul->flag & 2 && bul->flag & 8)
-			bBreak = true;
+			bBreak = TRUE;
 		if (bul->flag & 1 && bul->flag & 4)
-			bBreak = true;
+			bBreak = TRUE;
 	
 		if (!bul->direct && bul->flag & 1)
 			bul->direct = 2;
@@ -521,27 +521,8 @@
 		}
 		else
 		{
-			if (bul->act_no)
+			if (bul->act_no == 0)
 			{
-				if (bul->flag & 8)
-					bul->ym = -0x400;
-				else if (bul->flag & 1)
-					bul->xm = 0x400;
-				else if (bul->flag & 4)
-					bul->xm = -0x400;
-				
-				bul->ym += 85;
-				if (bul->ym >= 0x400)
-					bul->ym = 0x400;
-				
-				bul->x += bul->xm;
-				bul->y += bul->ym;
-				
-				if (bul->flag & 0xD)
-					PlaySoundObject(34, 1);
-			}
-			else
-			{
 				bul->act_no = 1;
 				
 				switch (bul->direct)
@@ -552,15 +533,15 @@
 					case 1:
 						bul->xm = gMC.xm;
 						
-						if (gMC.xm >= 0)
-							bul->direct = 2;
-						else
+						if (gMC.xm < 0)
 							bul->direct = 0;
-						
-						if (gMC.direct)
-							bul->xm += 0x80;
 						else
+							bul->direct = 2;
+						
+						if (gMC.direct == 0)
 							bul->xm -= 0x80;
+						else
+							bul->xm += 0x80;
 						
 						bul->ym = -0x5FF;
 						break;
@@ -569,40 +550,54 @@
 						break;
 					case 3:
 						bul->xm = gMC.xm;
-						if (gMC.xm >= 0)
-							bul->direct = 2;
-						else
+
+						if (gMC.xm < 0)
 							bul->direct = 0;
+						else
+							bul->direct = 2;
+
 						bul->ym = 0x5FF;
+
 						break;
 				}
 			}
+			else
+			{
+				if (bul->flag & 8)
+					bul->ym = -0x400;
+				else if (bul->flag & 1)
+					bul->xm = 0x400;
+				else if (bul->flag & 4)
+					bul->xm = -0x400;
+				
+				bul->ym += 85;
+				if (bul->ym > 0x3FF)
+					bul->ym = 0x3FF;
+				
+				bul->x += bul->xm;
+				bul->y += bul->ym;
+				
+				if (bul->flag & 0xD)
+					PlaySoundObject(34, 1);
+			}
 
-			RECT rect_left1[4] = {
-				{128, 0, 144, 16},
-				{144, 0, 160, 16},
-				{160, 0, 176, 16},
-				{176, 0, 192, 16},
-			};
+			SET_RECT(rect_left1[0], 128, 0, 144, 16)
+			SET_RECT(rect_left1[1], 144, 0, 160, 16)
+			SET_RECT(rect_left1[2], 160, 0, 176, 16)
+			SET_RECT(rect_left1[3], 176, 0, 192, 16)
 
-			RECT rect_right1[4] = {
-				{128, 16, 144, 32},
-				{144, 16, 160, 32},
-				{160, 16, 176, 32},
-				{176, 16, 192, 32},
-			};
+			SET_RECT(rect_right1[0], 128, 16, 144, 32)
+			SET_RECT(rect_right1[1], 144, 16, 160, 32)
+			SET_RECT(rect_right1[2], 160, 16, 176, 32)
+			SET_RECT(rect_right1[3], 176, 16, 192, 32)
 
-			RECT rect_left2[3] = {
-				{192, 16, 208, 32},
-				{208, 16, 224, 32},
-				{224, 16, 240, 32},
-			};
+			SET_RECT(rect_left2[0], 192, 16, 208, 32)
+			SET_RECT(rect_left2[1], 208, 16, 224, 32)
+			SET_RECT(rect_left2[2], 224, 16, 240, 32)
 
-			RECT rect_right2[3] = {
-				{224, 16, 240, 32},
-				{208, 16, 224, 32},
-				{192, 16, 208, 32},
-			};
+			SET_RECT(rect_right2[0], 224, 16, 240, 32)
+			SET_RECT(rect_right2[1], 208, 16, 224, 32)
+			SET_RECT(rect_right2[2], 192, 16, 208, 32)
 			
 			bul->ani_no++;
 			
@@ -611,10 +606,10 @@
 				if (bul->ani_no > 3)
 					bul->ani_no = 0;
 				
-				if (bul->direct)
-					bul->rect = rect_right1[bul->ani_no];
-				else
+				if (bul->direct == 0)
 					bul->rect = rect_left1[bul->ani_no];
+				else
+					bul->rect = rect_right1[bul->ani_no];
 			}
 			else
 			{
@@ -621,10 +616,10 @@
 				if (bul->ani_no > 2)
 					bul->ani_no = 0;
 				
-				if (bul->direct)
-					bul->rect = rect_right2[bul->ani_no];
-				else
+				if (bul->direct == 0)
 					bul->rect = rect_left2[bul->ani_no];
+				else
+					bul->rect = rect_right2[bul->ani_no];
 				
 				if (level == 2)
 					SetNpChar(129, bul->x, bul->y, 0, -0x200, bul->ani_no, 0, 0x100);
@@ -633,15 +628,12 @@
 			}
 		}
 	}
-	else
-	{
-		bul->cond = 0;
-		SetCaret(bul->x, bul->y, 3, 0);
-	}
 }
 
 void ActBullet_MachineGun(BULLET *bul, int level)
 {
+	int move;
+
 	RECT rect1[4] = {
 		{64, 0, 80, 16},
 		{80, 0, 96, 16},
@@ -670,32 +662,8 @@
 	}
 	else
 	{
-		if (bul->act_no)
+		if (bul->act_no == 0)
 		{
-			bul->x += bul->xm;
-			bul->y += bul->ym;
-			
-			switch ( level )
-			{
-				case 1:
-					bul->rect = rect1[bul->direct];
-					break;
-				case 2:
-					bul->rect = rect2[bul->direct];
-					if (bul->direct != 1 && bul->direct != 3)
-						SetNpChar(127, bul->x, bul->y, 0, 0, 0, 0, 256);
-					else
-						SetNpChar(127, bul->x, bul->y, 0, 0, 1, 0, 256);
-					break;
-				case 3:
-					bul->rect = rect3[bul->direct];
-					SetNpChar(128, bul->x, bul->y, 0, 0, bul->direct, 0, 256);
-					break;
-			}
-		}
-		else
-		{
-			int move;
 			switch (level)
 			{
 				case 1:
@@ -718,8 +686,8 @@
 					bul->ym = Random(-0xAA, 0xAA);
 					break;
 				case 1:
-					bul->xm = Random(-0xAA, 0xAA);
 					bul->ym = -move;
+					bul->xm = Random(-0xAA, 0xAA);
 					break;
 				case 2:
 					bul->xm = move;
@@ -726,16 +694,43 @@
 					bul->ym = Random(-0xAA, 0xAA);
 					break;
 				case 3:
-					bul->xm = Random(-0xAA, 0xAA);
 					bul->ym = move;
+					bul->xm = Random(-0xAA, 0xAA);
 					break;
 			}
 		}
+		else
+		{
+			bul->x += bul->xm;
+			bul->y += bul->ym;
+			
+			switch (level)
+			{
+				case 1:
+					bul->rect = rect1[bul->direct];
+					break;
+				case 2:
+					bul->rect = rect2[bul->direct];
+
+					if (bul->direct == 1 || bul->direct == 3)
+						SetNpChar(127, bul->x, bul->y, 0, 0, 1, 0, 256);
+					else
+						SetNpChar(127, bul->x, bul->y, 0, 0, 0, 0, 256);
+
+					break;
+				case 3:
+					bul->rect = rect3[bul->direct];
+					SetNpChar(128, bul->x, bul->y, 0, 0, bul->direct, 0, 256);
+					break;
+			}
+		}
 	}
 }
 
 void ActBullet_Missile(BULLET *bul, int level)
 {
+	BOOL bHit;
+
 	if (++bul->count1 > bul->life_count)
 	{
 		bul->cond = 0;
@@ -743,26 +738,26 @@
 		return;
 	}
 
-	bool bHit = false;
+	bHit = FALSE;
 
 	if (bul->life != 10)
-		bHit = true;
+		bHit = TRUE;
 	if (bul->direct == 0 && bul->flag & 1)
-		bHit = true;
+		bHit = TRUE;
 	if (bul->direct == 2 && bul->flag & 4)
-		bHit = true;
+		bHit = TRUE;
 	if (bul->direct == 1 && bul->flag & 2)
-		bHit = true;
+		bHit = TRUE;
 	if (bul->direct == 3 && bul->flag & 8)
-		bHit = true;
+		bHit = TRUE;
 	if (bul->direct == 0 && bul->flag & 0x80)
-		bHit = true;
+		bHit = TRUE;
 	if (bul->direct == 0 && bul->flag & 0x20)
-		bHit = true;
+		bHit = TRUE;
 	if (bul->direct == 2 && bul->flag & 0x40)
-		bHit = true;
+		bHit = TRUE;
 	if (bul->direct == 2 && bul->flag & 0x10)
-		bHit = true;
+		bHit = TRUE;
 
 	if (bHit)
 	{
@@ -793,7 +788,7 @@
 				{
 					case 0:
 					case 2:
-						if (gMC.y < bul->y)
+						if (bul->y > gMC.y)
 							bul->ym = 0x100;
 						else
 							bul->ym = -0x100;
@@ -803,7 +798,7 @@
 
 					case 1:
 					case 3:
-						if (gMC.x < bul->x)
+						if (bul->x > gMC.x)
 							bul->xm = 0x100;
 						else
 							bul->xm = -0x100;
@@ -836,10 +831,10 @@
 			switch (bul->direct)
 			{
 				case 0:
-					bul->xm -= bul->ani_no;
+					bul->xm += -bul->ani_no;
 					break;
 				case 1:
-					bul->ym -= bul->ani_no;
+					bul->ym += -bul->ani_no;
 					break;
 				case 2:
 					bul->xm += bul->ani_no;
@@ -855,7 +850,7 @@
 				{
 					case 0:
 					case 2:
-						if (bul->tgt_y > bul->y)
+						if (bul->y < bul->tgt_y)
 							bul->ym += 0x20;
 						else
 							bul->ym -= 0x20;
@@ -864,7 +859,7 @@
 
 					case 1:
 					case 3:
-						if (bul->tgt_x > bul->x)
+						if (bul->x < bul->tgt_x)
 							bul->xm += 0x20;
 						else
 							bul->xm -= 0x20;
@@ -951,8 +946,11 @@
 		case 0:
 			bul->act_no = 1;
 			
-			switch ( level )
+			switch (level)
 			{
+				case 1:
+					bul->act_wait = 10;
+					break;
 				case 2:
 					bul->act_wait = 15;
 					break;
@@ -959,57 +957,39 @@
 				case 3:
 					bul->act_wait = 5;
 					break;
-				case 1:
-					bul->act_wait = 10;
-					break;
 			}
 			
 			PlaySoundObject(44, 1);
 			// Fallthrough
 		case 1:
-			if (level == 1)
+			switch (level)
 			{
-				if (!(bul->act_wait % 3))
-					SetDestroyNpCharUp(bul->x + (Random(-16, 16) << 9), bul->y + (Random(-16, 16) << 9), bul->enemyXL, 2);
+				case 1:
+					if (bul->act_wait % 3 == 0)
+						SetDestroyNpCharUp(bul->x + (Random(-16, 16) << 9), bul->y + (Random(-16, 16) << 9), bul->enemyXL, 2);
+					break;
+
+				case 2:
+					if (bul->act_wait % 3 == 0)
+						SetDestroyNpCharUp(bul->x + (Random(-32, 32) << 9), bul->y + (Random(-32, 32) << 9), bul->enemyXL, 2);
+					break;
+
+				case 3:
+					if (bul->act_wait % 3 == 0)
+						SetDestroyNpCharUp(bul->x + (Random(-40, 40) << 9), bul->y + (Random(-40, 40) << 9), bul->enemyXL, 2);
+					break;
 			}
-			else if (level == 2)
-			{
-				if (!(bul->act_wait % 3))
-					SetDestroyNpCharUp(bul->x + (Random(-32, 32) << 9), bul->y + (Random(-32, 32) << 9), bul->enemyXL, 2);
-			}
-			else if (level == 3)
-			{
-				if (!(bul->act_wait % 3))
-					SetDestroyNpCharUp(bul->x + (Random(-40, 40) << 9), bul->y + (Random(-40, 40) << 9), bul->enemyXL, 2);
-			}
 			
 			if (--bul->act_wait < 0)
 				bul->cond = 0;
 			break;
 	}
-
-	if (level == 1)
-	{
-		 if (bul->act_wait % 3 == 0)
-			SetDestroyNpCharUp(bul->x + (Random(-16, 16) * 0x200), bul->y + (Random(-16, 16) * 0x200), bul->enemyXL, 2);
-	}
-	else if (level == 2)
-	{
-		if (bul->act_wait % 3 == 0)
-			SetDestroyNpCharUp(bul->x + (Random(-32, 32) * 0x200), bul->y + (Random(-32, 32) * 0x200), bul->enemyXL, 2);
-	}
-	else if (level == 3)
-	{
-		if (bul->act_wait % 3 == 0)
-			SetDestroyNpCharUp(bul->x + (Random(-40, 40) * 0x200), bul->y + (Random(-40, 40) * 0x200), bul->enemyXL, 2);
-	}
-
-	if (--bul->act_wait < 0)
-		bul->cond = 0;
 }
 
 void ActBullet_Bubblin1(BULLET *bul)
 {
+	RECT rect[4];
+
 	if (bul->flag & 0x2FF)
 	{
 		bul->cond = 0;
@@ -1017,25 +997,28 @@
 	}
 	else
 	{
-		if (bul->act_no == 0)
+		switch (bul->act_no)
 		{
-			bul->act_no = 1;
+			case 0:
+				bul->act_no = 1;
 
-			switch (bul->direct)
-			{
-				case 0:
-					bul->xm = -0x600;
-					break;
-				case 2:
-					bul->xm = 0x600;
-					break;
-				case 1:
-					bul->ym = -0x600;
-					break;
-				case 3:
-					bul->ym = 0x600;
-					break;
-			}
+				switch (bul->direct)
+				{
+					case 0:
+						bul->xm = -0x600;
+						break;
+					case 2:
+						bul->xm = 0x600;
+						break;
+					case 1:
+						bul->ym = -0x600;
+						break;
+					case 3:
+						bul->ym = 0x600;
+						break;
+				}
+
+				break;
 		}
 
 		switch (bul->direct)
@@ -1063,12 +1046,10 @@
 			SetCaret(bul->x, bul->y, 15, 0);
 		}
 
-		RECT rect[4] = {
-			{192, 0, 200, 8},
-			{200, 0, 208, 8},
-			{208, 0, 216, 8},
-			{216, 0, 224, 8},
-		};
+		SET_RECT(rect[0], 192, 0, 200, 8)
+		SET_RECT(rect[1], 200, 0, 208, 8)
+		SET_RECT(rect[2], 208, 0, 216, 8)
+		SET_RECT(rect[3], 216, 0, 224, 8)
 
 		if (++bul->ani_wait > 3)
 		{
@@ -1085,16 +1066,19 @@
 
 void ActBullet_Bubblin2(BULLET *bul)
 {
-	bool bDelete = false;
+	BOOL bDelete;
+	RECT rect[4];
 
+	bDelete = FALSE;
+
 	if (bul->direct == 0 && bul->flag & 1)
-		bDelete = true;
+		bDelete = TRUE;
 	if (bul->direct == 2 && bul->flag & 4)
-		bDelete = true;
+		bDelete = TRUE;
 	if (bul->direct == 1 && bul->flag & 2)
-		bDelete = true;
+		bDelete = TRUE;
 	if (bul->direct == 3 && bul->flag & 8)
-		bDelete = true;
+		bDelete = TRUE;
 
 	if (bDelete)
 	{
@@ -1103,29 +1087,32 @@
 	}
 	else
 	{
-		if (bul->act_no == 0)
+		switch (bul->act_no)
 		{
-			bul->act_no = 1;
+			case 0:
+				bul->act_no = 1;
 
-			switch (bul->direct)
-			{
-				case 0:
-					bul->xm = -0x600;
-					bul->ym = Random(-0x100, 0x100);
-					break;
-				case 2:
-					bul->xm = 0x600;
-					bul->ym = Random(-0x100, 0x100);
-					break;
-				case 1:
-					bul->ym = -0x600;
-					bul->xm = Random(-0x100, 0x100);
-					break;
-				case 3:
-					bul->ym = 0x600;
-					bul->xm = Random(-0x100, 0x100);
-					break;
-			}
+				switch (bul->direct)
+				{
+					case 0:
+						bul->xm = -0x600;
+						bul->ym = Random(-0x100, 0x100);
+						break;
+					case 2:
+						bul->xm = 0x600;
+						bul->ym = Random(-0x100, 0x100);
+						break;
+					case 1:
+						bul->ym = -0x600;
+						bul->xm = Random(-0x100, 0x100);
+						break;
+					case 3:
+						bul->ym = 0x600;
+						bul->xm = Random(-0x100, 0x100);
+						break;
+				}
+
+				break;
 		}
 
 		switch (bul->direct)
@@ -1153,12 +1140,10 @@
 			SetCaret(bul->x, bul->y, 15, 0);
 		}
 
-		RECT rect[4] = {
-			{192, 8, 200, 16},
-			{200, 8, 208, 16},
-			{208, 8, 216, 16},
-			{216, 8, 224, 16},
-		};
+		SET_RECT(rect[0], 192, 8, 200, 16)
+		SET_RECT(rect[1], 200, 8, 208, 16)
+		SET_RECT(rect[2], 208, 8, 216, 16)
+		SET_RECT(rect[3], 216, 8, 224, 16)
 
 		if (++bul->ani_wait > 3)
 		{
@@ -1175,41 +1160,57 @@
 
 void ActBullet_Bubblin3(BULLET *bul)
 {
-	if (++bul->act_wait <= 100 && gKey & gKeyShot)
+	if (++bul->act_wait > 100 || !(gKey & gKeyShot))
 	{
-		if (bul->act_no == 0)
+		bul->cond = 0;
+		SetCaret(bul->x, bul->y, 2, 0);
+		PlaySoundObject(100, 1);
+
+		if (gMC.up)
+			SetBullet(22, bul->x, bul->y, 1);
+		else if (gMC.down)
+			SetBullet(22, bul->x, bul->y, 3);
+		else
+			SetBullet(22, bul->x, bul->y, gMC.direct);
+	}
+	else
+	{
+		switch (bul->act_no)
 		{
-			bul->act_no = 1;
+			case 0:
+				bul->act_no = 1;
 
-			switch (bul->direct)
-			{
-				case 0:
-					bul->xm = Random(-0x400, -0x200);
-					bul->ym = (Random(-4, 4) * 0x200) / 2;
-					break;
-				case 2u:
-					bul->xm = Random(0x200, 0x400);
-					bul->ym = (Random(-4, 4) * 0x200) / 2;
-					break;
-				case 1u:
-					bul->ym = Random(-0x400, -0x200);
-					bul->xm = (Random(-4, 4) * 0x200) / 2;
-					break;
-				case 3u:
-					bul->ym = Random(0x80, 0x100);
-					bul->xm = (Random(-4, 4) * 0x200) / 2;
-					break;
-			}
+				switch (bul->direct)
+				{
+					case 0:
+						bul->xm = Random(-0x400, -0x200);
+						bul->ym = (Random(-4, 4) * 0x200) / 2;
+						break;
+					case 2:
+						bul->xm = Random(0x200, 0x400);
+						bul->ym = (Random(-4, 4) * 0x200) / 2;
+						break;
+					case 1:
+						bul->ym = Random(-0x400, -0x200);
+						bul->xm = (Random(-4, 4) * 0x200) / 2;
+						break;
+					case 3:
+						bul->ym = Random(0x80, 0x100);
+						bul->xm = (Random(-4, 4) * 0x200) / 2;
+						break;
+				}
+
+				break;
 		}
 
-		if (gMC.x > bul->x)
+		if (bul->x < gMC.x)
 			bul->xm += 0x20;
-		if (gMC.x < bul->x)
+		if (bul->x > gMC.x)
 			bul->xm -= 0x20;
 
-		if (gMC.y > bul->y)
+		if (bul->y < gMC.y)
 			bul->ym += 0x20;
-		if (gMC.y < bul->y)
+		if (bul->y > gMC.y)
 			bul->ym -= 0x20;
 
 		if (bul->xm < 0 && bul->flag & 1)
@@ -1243,19 +1244,6 @@
 
 		bul->rect = rect[bul->ani_no];
 	}
-	else
-	{
-		bul->cond = 0;
-		SetCaret(bul->x, bul->y, 2, 0);
-		PlaySoundObject(100, 1);
-
-		if (gMC.up)
-			SetBullet(22, bul->x, bul->y, 1);
-		else if (gMC.down)
-			SetBullet(22, bul->x, bul->y, 3);
-		else
-			SetBullet(22, bul->x, bul->y, gMC.direct);
-	}
 }
 
 void ActBullet_Spine(BULLET *bul)
@@ -1267,22 +1255,17 @@
 	}
 	else
 	{
-		if (bul->act_no)
+		if (bul->act_no == 0)
 		{
-			bul->x += bul->xm;
-			bul->y += bul->ym;
-		}
-		else
-		{
 			bul->act_no = 1;
 
 			switch (bul->direct)
 			{
 				case 0:
-					bul->xm = (-0x200 * Random(10, 16)) / 2;
+					bul->xm = (-Random(10, 16) * 0x200) / 2;
 					break;
 				case 1:
-					bul->ym = (-0x200 * Random(10, 16)) / 2;
+					bul->ym = (-Random(10, 16) * 0x200) / 2;
 					break;
 				case 2:
 					bul->xm = (Random(10, 16) * 0x200) / 2;
@@ -1292,6 +1275,11 @@
 					break;
 			}
 		}
+		else
+		{
+			bul->x += bul->xm;
+			bul->y += bul->ym;
+		}
 
 		if (++bul->ani_wait > 1)
 		{
@@ -1350,13 +1338,8 @@
 		if (bul->count1 % 5 == 1)
 			PlaySoundObject(34, 1);
 
-		if (bul->act_no)
+		if (bul->act_no == 0)
 		{
-			bul->x += bul->xm;
-			bul->y += bul->ym;
-		}
-		else
-		{
 			bul->act_no = 1;
 
 			switch (bul->direct)
@@ -1375,6 +1358,11 @@
 					break;
 			}
 		}
+		else
+		{
+			bul->x += bul->xm;
+			bul->y += bul->ym;
+		}
 
 		RECT rcLeft[4] = {
 			{0, 48, 16, 64},
@@ -1421,13 +1409,8 @@
 		if (bul->count1 % 7 == 1)
 			PlaySoundObject(106, 1);
 
-		if (bul->act_no)
+		if (bul->act_no == 0)
 		{
-			bul->x += bul->xm;
-			bul->y += bul->ym;
-		}
-		else
-		{
 			bul->act_no = 1;
 
 			switch (bul->direct)
@@ -1446,6 +1429,11 @@
 					break;
 			}
 		}
+		else
+		{
+			bul->x += bul->xm;
+			bul->y += bul->ym;
+		}
 
 		RECT rcLeft[4] = {
 			{160, 48, 184, 72},
@@ -1541,8 +1529,8 @@
 					SetBullet(23, bul->x, bul->y, 2);
 			}
 
-			if ( ++bul->count1 == 5 )
-				bul->bbits &= ~4u;
+			if (++bul->count1 == 5)
+				bul->bbits &= ~4;
 
 			if (bul->count1 > bul->life_count)
 			{
@@ -1657,16 +1645,18 @@
 
 void ActBullet_Drop(BULLET *bul)
 {
-	RECT rc[1] = {0, 0, 0, 0};
+	RECT rc = {0, 0, 0, 0};
 
 	if (++bul->act_wait > 2)
 		bul->cond = 0;
 
-	bul->rect = rc[0];
+	bul->rect = rc;
 }
 
 void ActBullet_SuperMissile(BULLET *bul, int level)
 {
+	BOOL bHit;
+
 	if (++bul->count1 > bul->life_count)
 	{
 		bul->cond = 0;
@@ -1674,26 +1664,26 @@
 		return;
 	}
 
-	bool bHit = false;
+	bHit = FALSE;
 
 	if (bul->life != 10)
-		bHit = true;
+		bHit = TRUE;
 	if (bul->direct == 0 && bul->flag & 1)
-		bHit = true;
+		bHit = TRUE;
 	if (bul->direct == 2 && bul->flag & 4)
-		bHit = true;
+		bHit = TRUE;
 	if (bul->direct == 1 && bul->flag & 2)
-		bHit = true;
+		bHit = TRUE;
 	if (bul->direct == 3 && bul->flag & 8)
-		bHit = true;
+		bHit = TRUE;
 	if (bul->direct == 0 && bul->flag & 0x80)
-		bHit = true;
+		bHit = TRUE;
 	if (bul->direct == 0 && bul->flag & 0x20)
-		bHit = true;
+		bHit = TRUE;
 	if (bul->direct == 2 && bul->flag & 0x40)
-		bHit = true;
+		bHit = TRUE;
 	if (bul->direct == 2 && bul->flag & 0x10)
-		bHit = true;
+		bHit = TRUE;
 
 	if (bHit)
 	{
@@ -1729,7 +1719,7 @@
 				{
 					case 0:
 					case 2:
-						if (gMC.y < bul->y)
+						if (bul->y > gMC.y)
 							bul->ym = 0x100;
 						else
 							bul->ym = -0x100;
@@ -1739,7 +1729,7 @@
 
 					case 1:
 					case 3:
-						if (gMC.x < bul->x)
+						if (bul->x > gMC.x)
 							bul->xm = 0x100;
 						else
 							bul->xm = -0x100;
@@ -1772,10 +1762,10 @@
 			switch (bul->direct)
 			{
 				case 0:
-					bul->xm -= bul->ani_no;
+					bul->xm += -bul->ani_no;
 					break;
 				case 1:
-					bul->ym -= bul->ani_no;
+					bul->ym += -bul->ani_no;
 					break;
 				case 2:
 					bul->xm += bul->ani_no;
@@ -1791,7 +1781,7 @@
 				{
 					case 0:
 					case 2:
-						if (bul->tgt_y > bul->y)
+						if (bul->y < bul->tgt_y)
 							bul->ym += 0x40;
 						else
 							bul->ym -= 0x40;
@@ -1799,7 +1789,7 @@
 						break;
 					case 1:
 					case 3:
-						if (bul->tgt_x > bul->x)
+						if (bul->x < bul->tgt_x)
 							bul->xm += 0x40;
 						else
 							bul->xm -= 0x40;
@@ -1896,21 +1886,21 @@
 			PlaySoundObject(44, 1);
 			// Fallthrough
 		case 1:
-			if (level == 1)
+			switch (level)
 			{
-				if (bul->act_wait % 3 == 0)
-					SetDestroyNpCharUp(bul->x + (Random(-16, 16) * 0x200), bul->y + (Random(-16, 16) * 0x200), bul->enemyXL, 2);
+				case 1:
+					if (bul->act_wait % 3 == 0)
+						SetDestroyNpCharUp(bul->x + (Random(-16, 16) * 0x200), bul->y + (Random(-16, 16) * 0x200), bul->enemyXL, 2);
+					break;
+				case 2:
+					if (bul->act_wait % 3 == 0)
+						SetDestroyNpCharUp(bul->x + (Random(-32, 32) * 0x200), bul->y + (Random(-32, 32) * 0x200), bul->enemyXL, 2);
+					break;
+				case 3:
+					if (bul->act_wait % 3 == 0)
+						SetDestroyNpCharUp(bul->x + (Random(-40, 40) * 0x200), bul->y + (Random(-40, 40) * 0x200), bul->enemyXL, 2);
+					break;
 			}
-			else if (level == 2)
-			{
-				if (bul->act_wait % 3 == 0)
-					SetDestroyNpCharUp(bul->x + (Random(-32, 32) * 0x200), bul->y + (Random(-32, 32) * 0x200), bul->enemyXL, 2);
-			}
-			else if (level == 3)
-			{
-				if (bul->act_wait % 3 == 0)
-					SetDestroyNpCharUp(bul->x + (Random(-40, 40) * 0x200), bul->y + (Random(-40, 40) * 0x200), bul->enemyXL, 2);
-			}
 
 			if (--bul->act_wait < 0)
 				bul->cond = 0;
@@ -1928,32 +1918,8 @@
 	}
 	else
 	{
-		if (bul->act_no)
+		if (bul->act_no == 0)
 		{
-			if (level == 1 && bul->count1 % 4 == 1)
-			{
-				switch (bul->direct)
-				{
-					case 0:
-						SetNpChar(4, bul->x, bul->y, -0x200, Random(-0x200, 0x200), 2, 0, 0x100);
-						break;
-					case 1:
-						SetNpChar(4, bul->x, bul->y, Random(-0x200, 0x200), -0x200, 2, 0, 0x100);
-						break;
-					case 2:
-						SetNpChar(4, bul->x, bul->y, 0x200, Random(-0x200, 0x200), 2, 0, 0x100);
-						break;
-					case 3:
-						SetNpChar(4, bul->x, bul->y, Random(-0x200, 0x200), 0x200, 2, 0, 0x100);
-						break;
-				}
-			}
-
-			bul->x += bul->xm;
-			bul->y += bul->ym;
-		}
-		else
-		{
 			bul->act_no = 1;
 			bul->count1 = 0;
 
@@ -1973,13 +1939,39 @@
 					break;
 			}
 
-			if (level == 3)
+			switch (level)
 			{
-				bul->xm /= 3;
-				bul->ym /= 3;
+				case 3:
+					bul->xm /= 3;
+					bul->ym /= 3;
+					break;
 			}
 		}
+		else
+		{
+			if (level == 1 && bul->count1 % 4 == 1)
+			{
+				switch (bul->direct)
+				{
+					case 0:
+						SetNpChar(4, bul->x, bul->y, -0x200, Random(-0x200, 0x200), 2, 0, 0x100);
+						break;
+					case 1:
+						SetNpChar(4, bul->x, bul->y, Random(-0x200, 0x200), -0x200, 2, 0, 0x100);
+						break;
+					case 2:
+						SetNpChar(4, bul->x, bul->y, 0x200, Random(-0x200, 0x200), 2, 0, 0x100);
+						break;
+					case 3:
+						SetNpChar(4, bul->x, bul->y, Random(-0x200, 0x200), 0x200, 2, 0, 0x100);
+						break;
+				}
+			}
 
+			bul->x += bul->xm;
+			bul->y += bul->ym;
+		}
+
 		if (++bul->ani_no > 1)
 			bul->ani_no = 0;
 
@@ -2038,13 +2030,8 @@
 		if (bul->damage && bul->life != 100)
 			bul->damage = 0;
 
-		if (bul->act_no)
+		if (bul->act_no == 0)
 		{
-			bul->x += bul->xm;
-			bul->y += bul->ym;
-		}
-		else
-		{
 			bul->act_no = 1;
 
 			switch (bul->direct)
@@ -2063,43 +2050,52 @@
 					break;
 			}
 
-			if (level == 1)
+			switch (level)
 			{
-				switch (bul->direct)
-				{
-					case 0:
-						bul->enemyYL = 0x400;
-						break;
-					case 1:
-						bul->enemyXL = 0x400;
-						break;
-					case 2:
-						bul->enemyYL = 0x400;
-						break;
-					case 3:
-						bul->enemyXL = 0x400;
-						break;
-				}
+				case 1:
+					switch (bul->direct)
+					{
+						case 0:
+							bul->enemyYL = 0x400;
+							break;
+						case 1:
+							bul->enemyXL = 0x400;
+							break;
+						case 2:
+							bul->enemyYL = 0x400;
+							break;
+						case 3:
+							bul->enemyXL = 0x400;
+							break;
+					}
+
+					break;
+
+				case 2:
+					switch (bul->direct)
+					{
+						case 0:
+							bul->enemyYL = 0x800;
+							break;
+						case 1:
+							bul->enemyXL = 0x800;
+							break;
+						case 2:
+							bul->enemyYL = 0x800;
+							break;
+						case 3:
+							bul->enemyXL = 0x800;
+							break;
+					}
+
+					break;
 			}
-			else if (level == 2)
-			{
-				switch (bul->direct)
-				{
-					case 0:
-						bul->enemyYL = 0x800;
-						break;
-					case 1:
-						bul->enemyXL = 0x800;
-						break;
-					case 2:
-						bul->enemyYL = 0x800;
-						break;
-					case 3:
-						bul->enemyXL = 0x800;
-						break;
-				}
-			}
 		}
+		else
+		{
+			bul->x += bul->xm;
+			bul->y += bul->ym;
+		}
 
 		RECT rect1[2] = {
 			{128, 32, 144, 48},
@@ -2248,8 +2244,13 @@
 	{
 		if (gBul[i].cond & 0x80)
 		{
-			if (gBul[i].life > 0)
+			if (gBul[i].life < 1)
 			{
+				gBul[i].cond = 0;
+				continue;
+			}
+			else
+			{
 				switch (gBul[i].code_bullet)
 				{
 					case 1:
@@ -2387,13 +2388,7 @@
 					case 45:
 						ActBullet_Star(&gBul[i]);
 						break;
-					default:
-						continue;
 				}
-			}
-			else
-			{
-				gBul[i].cond = 0;
 			}
 		}
 	}
--- a/src/WindowsWrapper.h
+++ b/src/WindowsWrapper.h
@@ -13,6 +13,12 @@
 #define TRUE 1
 #endif
 
+#define SET_RECT(rect, l, t, r, b) \
+	rect.left = l; \
+	rect.top = t; \
+	rect.right = r; \
+	rect.bottom = b;
+
 struct RECT
 {
 	union