shithub: cstory

Download patch

ref: 4fb84866a5cd17eb9e1f2fdc10cbb9e3937164d5
parent: 17b0b503a940ef0cfb70ed1506a3132c0b6146d6
author: cuckydev <cuckydev@users.noreply.github.com>
date: Sat Jan 26 17:15:10 EST 2019

stuff

--- a/src/Caret.cpp
+++ b/src/Caret.cpp
@@ -4,6 +4,7 @@
 
 #include "Caret.h"
 #include "Draw.h"
+#include "Game.h"
 
 #define CARET_MAX 0x40
 CARET gCrt[CARET_MAX];
@@ -18,6 +19,61 @@
 	;
 }
 
+void ActCaret01(CARET *crt)
+{
+	RECT rcLeft[4];
+	RECT rcRight[4];
+	
+	rcLeft[0] = {0, 64, 8, 72};
+	rcLeft[1] = {8, 64, 16, 72};
+	rcLeft[2] = {16, 64, 24, 72};
+	rcLeft[3] = {24, 64, 32, 72};
+	
+	rcRight[0] = {64, 24, 72, 32};
+	rcRight[1] = {72, 24, 80, 32};
+	rcRight[2] = {80, 24, 88, 32};
+	rcRight[3] = {88, 24, 92, 32};
+	
+	if (!crt->act_no)
+	{
+		crt->act_no = 1;
+		crt->xm = Random(-0x400, 0x400);
+		crt->ym = Random(-0x400, 0);
+	}
+	
+	crt->ym += 0x40;
+	crt->x += crt->xm;
+	crt->y += crt->ym;
+	
+	if (++crt->ani_wait > 5)
+	{
+		crt->ani_wait = 0;
+		if (++crt->ani_no > 3)
+			crt->cond = 0;
+	}
+	
+	if (crt->direct)
+		crt->rect = rcRight[crt->ani_no];
+	else
+		crt->rect = rcLeft[crt->ani_no];
+}
+
+
+
+
+void ActCaret09(CARET *crt)
+{
+	if (++crt->ani_wait <= 4)
+		crt->y -= 0x800;
+	if (crt->ani_wait == 32 )
+		crt->cond = 0;
+	
+	if (crt->direct)
+		crt->rect = {48, 64, 64, 80};
+	else
+		crt->rect = {0, 80, 16, 96};
+}
+
 //Tables
 CARET_TABLE gCaretTable[18] =
 {
@@ -45,7 +101,7 @@
 CARETFUNCTION gpCaretFuncTbl[] =
 {
 	&ActCaret00,
-	nullptr, //&ActCaret01,
+	&ActCaret01,
 	nullptr, //&ActCaret02,
 	nullptr, //&ActCaret03,
 	nullptr, //&ActCaret04,
@@ -53,7 +109,7 @@
 	nullptr, //&ActCaret04,
 	nullptr, //&ActCaret07,
 	nullptr, //&ActCaret08,
-	nullptr, //&ActCaret09,
+	&ActCaret09,
 	nullptr, //&ActCaret10,
 	nullptr, //&ActCaret11,
 	nullptr, //&ActCaret12,
@@ -61,7 +117,7 @@
 	nullptr, //&ActCaret14,
 	nullptr, //&ActCaret15,
 	nullptr, //&ActCaret16,
-	nullptr //&ActCaret17
+	nullptr, //&ActCaret17
 };
 
 void ActCaret()
@@ -68,8 +124,11 @@
 {
 	for (int i = 0; i < CARET_MAX; i++)
 	{
-		if (gCrt[i].cond & 0x80 && gpCaretFuncTbl[gCrt[i].code] != nullptr)
+		if ((gCrt[i].cond & 0x80) && gpCaretFuncTbl[gCrt[i].code] != nullptr)
+		{
+			printf("ActCaret%02d\n", gCrt[i].code);
 			gpCaretFuncTbl[gCrt[i].code](&gCrt[i]);
+		}
 	}
 }
 
@@ -93,7 +152,7 @@
 {
 	for (int c = 0; c < CARET_MAX; c++)
 	{
-		if (gCrt[c].cond)
+		if (!gCrt[c].cond)
 		{
 			memset(&gCrt[c], 0, sizeof(CARET));
 			gCrt[c].cond = 0x80;
--- a/src/Draw.cpp
+++ b/src/Draw.cpp
@@ -309,7 +309,7 @@
 void Surface2Surface(int x, int y, RECT *rect, int to, int from)
 {
 	//Get rects
-	SDL_Rect rcSet = {x * gWindowScale, y * gWindowScale, (x + rect->right - rect->left) * gWindowScale, (y + rect->bottom - rect->top) * gWindowScale};
+	SDL_Rect rcSet = {x * gWindowScale, y * gWindowScale, (rect->right - rect->left) * gWindowScale, (rect->bottom - rect->top) * gWindowScale};
 	SDL_Rect frameRect = RectToSDLRect(rect);
 	frameRect = {frameRect.x * gWindowScale, frameRect.y * gWindowScale, frameRect.w * gWindowScale, frameRect.h * gWindowScale};
 	
--- a/src/Frame.cpp
+++ b/src/Frame.cpp
@@ -89,8 +89,8 @@
 	int16_t map_w, map_l;
 	GetMapData(0, &map_w, &map_l);
 	
-	gFrame.x = mc_x - (WINDOW_WIDTH << 9);
-	gFrame.y = mc_y - (WINDOW_HEIGHT << 9);
+	gFrame.x = mc_x - (WINDOW_WIDTH << 8);
+	gFrame.y = mc_y - (WINDOW_HEIGHT << 8);
 	
 	//Keep in bounds
 	if (gFrame.x <= -0x200)
--- a/src/Game.cpp
+++ b/src/Game.cpp
@@ -136,12 +136,12 @@
 		ActBack();
 		ResetMyCharFlag();
 		HitMyCharMap();
-		//HitMyCharNpChar();
+		HitMyCharNpChar();
 		//HitMyCharBoss();
 		HitNpCharMap();
 		//HitBossMap();
 		//HitBossBullet();
-		//ActCaret();
+		ActCaret();
 		MoveFrame3();
 		ProcFade();
 		
@@ -157,7 +157,7 @@
 		PutMapDataVector(frame_x, frame_y);
 		PutStage_Front(frame_x, frame_y);
 		PutFront(frame_x, frame_y);
-		//PutCaret(frame_x, frame_y);
+		PutCaret(frame_x, frame_y);
 		PutFade();
 		
 		//Update Text Script
@@ -471,7 +471,7 @@
 				ActBack();
 				ResetMyCharFlag();
 				HitMyCharMap();
-				//HitMyCharNpChar();
+				HitMyCharNpChar();
 				//HitMyCharBoss();
 				HitNpCharMap();
 				//HitBossMap();
--- a/src/MycHit.cpp
+++ b/src/MycHit.cpp
@@ -3,10 +3,13 @@
 #include "WindowsWrapper.h"
 
 #include "MyChar.h"
+#include "NpChar.h"
 #include "Map.h"
 #include "Sound.h"
 #include "Caret.h"
 #include "Back.h"
+#include "Game.h"
+#include "TextScr.h"
 #include "KeyControl.h"
 
 void ResetMyCharFlag()
@@ -565,3 +568,261 @@
 	if (gMC.y > gWaterY + 0x800)
 		gMC.flag |= 0x100;
 }
+
+int JudgeHitMyCharNPC(NPCHAR *npc)
+{
+	int hit = 0;
+	
+	if (gMC.y - gMC.hit.top < npc->y + npc->hit.bottom - 0x600
+		&& gMC.y + gMC.hit.bottom > npc->y - npc->hit.top + 0x600
+		&& gMC.x - gMC.hit.right < npc->x + npc->hit.back
+		&& gMC.x - gMC.hit.right > npc->x)
+	{
+		if (gMC.xm < 0x200)
+			gMC.xm += 0x200;
+		hit |= 1;
+	}
+	
+	if (gMC.y - gMC.hit.top < npc->y + npc->hit.bottom - 0x600
+		&& gMC.y + gMC.hit.bottom > npc->y - npc->hit.top + 0x600
+		&& gMC.x + gMC.hit.right - 0x200 > npc->x - npc->hit.back
+		&& gMC.x + gMC.hit.right - 0x200 < npc->x)
+	{
+		if (gMC.xm > -0x200)
+			gMC.xm -= 0x200;
+		hit |= 4;
+	}
+	
+	if (gMC.x - gMC.hit.right < npc->x + npc->hit.back - 0x600
+		&& gMC.x + gMC.hit.right > npc->x - npc->hit.back + 0x600
+		&& gMC.y - gMC.hit.top < npc->y + npc->hit.bottom
+		&& gMC.y - gMC.hit.top > npc->y)
+	{
+		if (gMC.ym < 0)
+			gMC.ym = 0;
+		hit |= 2;
+	}
+	
+	if (gMC.x - gMC.hit.right < npc->x + npc->hit.back - 0x600
+		&& gMC.x + gMC.hit.right > npc->x - npc->hit.back + 0x600
+		&& gMC.y + gMC.hit.bottom > npc->y - npc->hit.top
+		&& gMC.hit.bottom + gMC.y < npc->y + 0x600)
+	{
+		if (npc->bits & npc_bouncy)
+		{
+			gMC.ym = npc->ym - 0x200;
+			hit |= 8;
+		}
+		else if (!(gMC.flag & 8) && gMC.ym > npc->ym)
+		{
+			gMC.y = npc->y - npc->hit.top - gMC.hit.bottom + 0x200;
+			gMC.ym = npc->ym;
+			gMC.x += npc->xm;
+			hit |= 8;
+		}
+	}
+	return hit;
+}
+
+int JudgeHitMyCharNPC3(NPCHAR *npc)
+{
+	if (npc->direct)
+	{
+		if (gMC.x + 0x400 > npc->x - npc->hit.back
+			&& gMC.x - 0x400 < npc->x + npc->hit.front
+			&& gMC.y + 0x400 > npc->y - npc->hit.top
+			&& gMC.y - 0x400 < npc->y + npc->hit.bottom)
+			return 1;
+	}
+	else
+	{
+		if (gMC.x + 0x400 > npc->x - npc->hit.front
+			&& gMC.x - 0x400 < npc->x + npc->hit.back
+			&& gMC.y + 0x400 > npc->y - npc->hit.top
+			&& gMC.y - 0x400 < npc->y + npc->hit.bottom)
+			return 1;
+	}
+	
+	return 0;
+}
+
+int JudgeHitMyCharNPC4(NPCHAR *npc)
+{
+	//TODO: comment this
+	int hit = 0;
+	long double v1, v2;
+	
+	if (npc->x <= gMC.x)
+		v1 = (long double)(gMC.x - npc->x);
+	else
+		v1 = (long double)(npc->x - gMC.x);
+	
+	float fx1 = v1;
+	
+	if (npc->y <= gMC.y)
+		v2 = (long double)(gMC.y - npc->y);
+	else
+		v2 = (long double)(npc->y - gMC.y);
+	
+	float fx2 = (long double)npc->hit.back;
+	if (0.0 == fx1)
+		fx1 = 1.0;
+	if (0.0 == fx2)
+		fx2 = 1.0;
+	
+	float fy1 = v2;
+	float fy2 = (long double)npc->hit.top;
+	
+	if (fy1 / fx1 <= fy2 / fx2)
+	{
+		if (gMC.y - gMC.hit.top < npc->y + npc->hit.bottom && gMC.y + gMC.hit.bottom > npc->y - npc->hit.top)
+		{
+			if (gMC.x - gMC.hit.right < npc->x + npc->hit.back && gMC.x - gMC.hit.right > npc->x)
+			{
+				if ( gMC.xm < npc->xm )
+					gMC.xm = npc->xm;
+				gMC.x = npc->hit.back + npc->x + gMC.hit.right;
+				hit |= 1;
+			}
+			
+			if (gMC.x + gMC.hit.right > npc->x - npc->hit.back && gMC.hit.right + gMC.x < npc->x)
+			{
+				if ( gMC.xm > npc->xm )
+					gMC.xm = npc->xm;
+				gMC.x = npc->x - npc->hit.back - gMC.hit.right;
+				hit |= 4;
+			}
+		}
+	}
+	else if (gMC.x - gMC.hit.right < npc->x + npc->hit.back && gMC.x + gMC.hit.right > npc->x - npc->hit.back)
+	{
+		if (gMC.y - gMC.hit.top < npc->y + npc->hit.bottom && gMC.y - gMC.hit.top > npc->y)
+		{
+			if (gMC.ym >= npc->ym)
+			{
+				if (gMC.ym < 0)
+					gMC.ym = 0;
+			}
+			else
+			{
+				gMC.y = npc->hit.bottom + npc->y + gMC.hit.top + 0x200;
+				gMC.ym = npc->ym;
+			}
+			
+			hit |= 2;
+		}
+		
+		if (gMC.y + gMC.hit.bottom > npc->y - npc->hit.top && gMC.hit.bottom + gMC.y < npc->y + 0x600)
+		{
+			if (gMC.ym - npc->ym > 0x400)
+				PlaySoundObject(23, 1);
+			
+			if (gMC.unit == 1)
+			{
+				gMC.y = npc->y - npc->hit.top - gMC.hit.bottom + 0x200;
+				hit |= 8;
+			}
+			else if (npc->bits & npc_bouncy)
+			{
+				gMC.ym = npc->ym - 0x200;
+				hit |= 8;
+			}
+			else if (!(gMC.flag & 8) && gMC.ym > npc->ym)
+			{
+				gMC.y = npc->y - npc->hit.top - gMC.hit.bottom + 0x200;
+				gMC.ym = npc->ym;
+				gMC.x += npc->xm;
+				hit |= 8;
+			}
+		}
+	}
+	
+	return hit;
+}
+
+void HitMyCharNpChar()
+{
+	if ((gMC.cond & 0x80) && !(gMC.cond & 2))
+	{
+		int hit;
+		
+		for (int i = 0; i < NPC_MAX; i++)
+		{
+			if (gNPC[i].cond & 0x80)
+			{
+				if (gNPC[i].bits & npc_solidSoft)
+				{
+					hit = JudgeHitMyCharNPC(&gNPC[i]);
+					gMC.flag |= hit;
+				}
+				else if (gNPC[i].bits & npc_solidHard)
+				{
+					hit = JudgeHitMyCharNPC4(&gNPC[i]);
+					gMC.flag |= hit;
+				}
+				else
+				{
+					hit = JudgeHitMyCharNPC3(&gNPC[i]);
+				}
+				
+				//Special NPCs (pickups)
+				if (hit && gNPC[i].code_char == 1)
+				{
+					PlaySoundObject(14, 1);
+					//AddExpMyChar(gNPC[i].exp);
+					gNPC[i].cond = 0;
+				}
+				
+				if (hit && gNPC[i].code_char == 86)
+				{
+					PlaySoundObject(42, 1);
+					//AddBulletMyChar(gNPC[i].code_event, gNPC[i].exp);
+					gNPC[i].cond = 0;
+				}
+				
+				if (hit && gNPC[i].code_char == 87)
+				{
+					PlaySoundObject(20, 1);
+					//AddLifeMyChar(gNPC[i].exp);
+					gNPC[i].cond = 0;
+				}
+				
+				//Run event on contact
+				if (!(g_GameFlags & 4) && hit && gNPC[i].bits & npc_eventTouch)
+					StartTextScript(gNPC[i].code_event);
+				
+				//NPC damage
+				if (g_GameFlags & 2 && !(gNPC[i].bits & npc_interact))
+				{
+					if (gNPC[i].bits & npc_rearTop)
+					{
+						//if (hit & 4 && gNPC[i].xm < 0)
+						//	DamageMyChar(gNPC[i].damage);
+						//if (hit & 1 && gNPC[i].xm > 0)
+						//	DamageMyChar(gNPC[i].damage);
+						//if (hit & 8 && gNPC[i].ym < 0)
+						//	DamageMyChar(gNPC[i].damage);
+						//if (hit & 2 && gNPC[i].ym > 0)
+						//	DamageMyChar(gNPC[i].damage);
+					}
+					else if (hit && gNPC[i].damage && !(g_GameFlags & 4))
+					{
+						//DamageMyChar(gNPC[i].damage);
+					}
+				}
+				
+				//Interaction
+				if (!(g_GameFlags & 4) && hit && gMC.cond & 1 && gNPC[i].bits & npc_interact)
+				{
+					StartTextScript(gNPC[i].code_event);
+					gMC.xm = 0;
+					gMC.ques = 0;
+				}
+			}
+		}
+		
+		//Create question mark when NPC hasn't been interacted with
+		if (gMC.ques)
+			SetCaret(gMC.x, gMC.y, 9, 0);
+	}
+}
\ No newline at end of file
--- a/src/MycHit.h
+++ b/src/MycHit.h
@@ -1,3 +1,4 @@
 #pragma once
 void ResetMyCharFlag();
 void HitMyCharMap();
+void HitMyCharNpChar();
--- a/src/Stage.cpp
+++ b/src/Stage.cpp
@@ -197,19 +197,22 @@
 
 void ChangeMusic(int no)
 {
-	//Stop and keep track of old song
-	gOldPos = GetOrganyaPosition();
-    gOldNo = gMusicNo;
-    StopOrganyaMusic();
-	
-	//Load .org
-	LoadOrganya(gMusicTable[no]);
-	
-	//Reset position, volume, and then play the song
-    ChangeOrganyaVolume(100);
-    SetOrganyaPosition(0);
-    PlayOrganyaMusic();
-    gMusicNo = no;
+	if (!no || no != gMusicNo)
+	{
+		//Stop and keep track of old song
+		gOldPos = GetOrganyaPosition();
+		gOldNo = gMusicNo;
+		StopOrganyaMusic();
+		
+		//Load .org
+		LoadOrganya(gMusicTable[no]);
+		
+		//Reset position, volume, and then play the song
+		ChangeOrganyaVolume(100);
+		SetOrganyaPosition(0);
+		PlayOrganyaMusic();
+		gMusicNo = no;
+	}
 }
 
 void ReCallMusic()
--- a/src/TextScr.cpp
+++ b/src/TextScr.cpp
@@ -19,6 +19,8 @@
 #include "Organya.h"
 #include "Game.h"
 
+#define IS_COMMAND(c1, c2, c3) gTS.data[gTS.p_read + 1] == c1 && gTS.data[gTS.p_read + 2] == c2 && gTS.data[gTS.p_read + 3] == c3
+
 #define TSC_BUFFER_SIZE 0x5000
 
 TEXT_SCRIPT gTS;
@@ -540,9 +542,7 @@
 				}
 				else
 				{
-					if (gTS.data[gTS.p_read + 1] == 'E' &&
-						gTS.data[gTS.p_read + 2] == 'N' &&
-						gTS.data[gTS.p_read + 3] == 'D')
+					if (IS_COMMAND('E','N','D'))
 					{
 						gTS.mode = 0;
 						gMC.cond &= ~1;
@@ -550,9 +550,7 @@
 						gTS.face = 0;
 						bExit = true;
 					}
-					else if (gTS.data[gTS.p_read + 1] == 'T' &&
-							 gTS.data[gTS.p_read + 2] == 'R' &&
-							 gTS.data[gTS.p_read + 3] == 'A')
+					else if (IS_COMMAND('T','R','A'))
 					{
 						int z = GetTextScriptNo(gTS.p_read + 4);
 						int w = GetTextScriptNo(gTS.p_read + 9);
@@ -561,41 +559,31 @@
 						if (!TransferStage(z, w, x, y))
 							return 0;
 					}
-					else if (gTS.data[gTS.p_read + 1] == 'F' &&
-							 gTS.data[gTS.p_read + 2] == 'L' &&
-							 gTS.data[gTS.p_read + 3] == '+')
+					else if (IS_COMMAND('F','L','+'))
 					{
 						int z = GetTextScriptNo(gTS.p_read + 4);
 						SetNPCFlag(z);
 						gTS.p_read += 8;
 					}
-					else if (gTS.data[gTS.p_read + 1] == 'F' &&
-							 gTS.data[gTS.p_read + 2] == 'L' &&
-							 gTS.data[gTS.p_read + 3] == '-')
+					else if (IS_COMMAND('F','L','-'))
 					{
 						int z = GetTextScriptNo(gTS.p_read + 4);
 						CutNPCFlag(z);
 						gTS.p_read += 8;
 					}
-					else if (gTS.data[gTS.p_read + 1] == 'S' &&
-							 gTS.data[gTS.p_read + 2] == 'K' &&
-							 gTS.data[gTS.p_read + 3] == '+')
+					else if (IS_COMMAND('S','K','+'))
 					{
 						int z = GetTextScriptNo(gTS.p_read + 4);
 						SetSkipFlag(z);
 						gTS.p_read += 8;
 					}
-					else if (gTS.data[gTS.p_read + 1] == 'S' &&
-							 gTS.data[gTS.p_read + 2] == 'K' &&
-							 gTS.data[gTS.p_read + 3] == '-')
+					else if (IS_COMMAND('S','K','-'))
 					{
 						int z = GetTextScriptNo(gTS.p_read + 4);
 						CutSkipFlag(z);
 						gTS.p_read += 8;
 					}
-					else if (gTS.data[gTS.p_read + 1] == 'K' &&
-							 gTS.data[gTS.p_read + 2] == 'E' &&
-							 gTS.data[gTS.p_read + 3] == 'Y')
+					else if (IS_COMMAND('K','E','Y'))
 					{
 						g_GameFlags &= ~2;
 						g_GameFlags |= 1;
@@ -603,39 +591,29 @@
 						gMC.shock = 0;
 						gTS.p_read += 4;
 					}
-					else if (gTS.data[gTS.p_read + 1] == 'P' &&
-							 gTS.data[gTS.p_read + 2] == 'R' &&
-							 gTS.data[gTS.p_read + 3] == 'I')
+					else if (IS_COMMAND('P','R','I'))
 					{
 						g_GameFlags &= ~3;
 						gMC.shock = 0;
 						gTS.p_read += 4;
 					}
-					else if (gTS.data[gTS.p_read + 1] == 'F' &&
-							 gTS.data[gTS.p_read + 2] == 'R' &&
-							 gTS.data[gTS.p_read + 3] == 'E')
+					else if (IS_COMMAND('F','R','E'))
 					{
 						g_GameFlags |= 3;
 						gTS.p_read += 4;
 					}
-					else if (gTS.data[gTS.p_read + 1] == 'N' &&
-							 gTS.data[gTS.p_read + 2] == 'O' &&
-							 gTS.data[gTS.p_read + 3] == 'D')
+					else if (IS_COMMAND('N','O','D'))
 					{
 						gTS.mode = 2;
 						gTS.p_read += 4;
 						bExit = true;
 					}
-					else if (gTS.data[gTS.p_read + 1] == 'C' &&
-							 gTS.data[gTS.p_read + 2] == 'L' &&
-							 gTS.data[gTS.p_read + 3] == 'R')
+					else if (IS_COMMAND('C','L','R'))
 					{
 						ClearTextLine();
 						gTS.p_read += 4;
 					}
-					else if (gTS.data[gTS.p_read + 1] == 'M' &&
-							 gTS.data[gTS.p_read + 2] == 'S' &&
-							 gTS.data[gTS.p_read + 3] == 'G')
+					else if (IS_COMMAND('M','S','G'))
 					{
 						ClearTextLine();
 						gTS.flags |= 0x03;
@@ -645,9 +623,7 @@
 						gTS.p_read += 4;
 						bExit = true;
 					}
-					else if (gTS.data[gTS.p_read + 1] == 'M' &&
-							 gTS.data[gTS.p_read + 2] == 'S' &&
-							 gTS.data[gTS.p_read + 3] == '2')
+					else if (IS_COMMAND('M','S','2'))
 					{
 						ClearTextLine();
 						gTS.flags |= 0x21;
@@ -658,9 +634,7 @@
 						gTS.p_read += 4;
 						bExit = true;
 					}
-					else if (gTS.data[gTS.p_read + 1] == 'M' &&
-							 gTS.data[gTS.p_read + 2] == 'S' &&
-							 gTS.data[gTS.p_read + 3] == '3')
+					else if (IS_COMMAND('M','S','3'))
 					{
 						ClearTextLine();
 						gTS.flags |= 0x23;
@@ -670,9 +644,7 @@
 						gTS.p_read += 4;
 						bExit = true;
 					}
-					else if (gTS.data[gTS.p_read + 1] == 'W' &&
-							 gTS.data[gTS.p_read + 2] == 'A' &&
-							 gTS.data[gTS.p_read + 3] == 'I')
+					else if (IS_COMMAND('W','A','I'))
 					{
 						gTS.mode = 4;
 						gTS.wait_next = GetTextScriptNo(gTS.p_read + 4);
@@ -679,30 +651,22 @@
 						gTS.p_read += 8;
 						bExit = true;
 					}
-					else if (gTS.data[gTS.p_read + 1] == 'T' &&
-							 gTS.data[gTS.p_read + 2] == 'U' &&
-							 gTS.data[gTS.p_read + 3] == 'R')
+					else if (IS_COMMAND('T','U','R'))
 					{
 						gTS.p_read += 4;
 						gTS.flags |= 0x10;
 					}
-					else if (gTS.data[gTS.p_read + 1] == 'S' &&
-							 gTS.data[gTS.p_read + 2] == 'A' &&
-							 gTS.data[gTS.p_read + 3] == 'T')
+					else if (IS_COMMAND('S','A','T'))
 					{
 						gTS.p_read += 4;
 						gTS.flags |= 0x40;
 					}
-					else if (gTS.data[gTS.p_read + 1] == 'C' &&
-							 gTS.data[gTS.p_read + 2] == 'A' &&
-							 gTS.data[gTS.p_read + 3] == 'T')
+					else if (IS_COMMAND('C','A','T'))
 					{
 						gTS.p_read += 4;
 						gTS.flags |= 0x40;
 					}
-					else if (gTS.data[gTS.p_read + 1] == 'F' &&
-							 gTS.data[gTS.p_read + 2] == 'L' &&
-							 gTS.data[gTS.p_read + 3] == 'J')
+					else if (IS_COMMAND('F','L','J'))
 					{
 						int x = GetTextScriptNo(gTS.p_read + 4);
 						int z = GetTextScriptNo(gTS.p_read + 9);
@@ -712,9 +676,7 @@
 						else
 							gTS.p_read += 13;
 					}
-					else if (gTS.data[gTS.p_read + 1] == 'S' &&
-							 gTS.data[gTS.p_read + 2] == 'K' &&
-							 gTS.data[gTS.p_read + 3] == 'J')
+					else if (IS_COMMAND('S','K','J'))
 					{
 						int x = GetTextScriptNo(gTS.p_read + 4);
 						int z = GetTextScriptNo(gTS.p_read + 9);
@@ -724,9 +686,7 @@
 						else
 							gTS.p_read += 13;
 					}
-					else if (gTS.data[gTS.p_read + 1] == 'F' &&
-							 gTS.data[gTS.p_read + 2] == 'A' &&
-							 gTS.data[gTS.p_read + 3] == 'I')
+					else if (IS_COMMAND('F','A','I'))
 					{
 						int z = GetTextScriptNo(gTS.p_read + 4);
 						StartFadeIn(z);
@@ -734,9 +694,7 @@
 						gTS.p_read += 8;
 						bExit = true;
 					}
-					else if (gTS.data[gTS.p_read + 1] == 'F' &&
-							 gTS.data[gTS.p_read + 2] == 'A' &&
-							 gTS.data[gTS.p_read + 3] == 'O')
+					else if (IS_COMMAND('F','A','O'))
 					{
 						int z = GetTextScriptNo(gTS.p_read + 4);
 						StartFadeOut(z);
@@ -744,31 +702,29 @@
 						gTS.p_read += 8;
 						bExit = true;
 					}
-					else if (gTS.data[gTS.p_read + 1] == 'M' &&
-							 gTS.data[gTS.p_read + 2] == 'N' &&
-							 gTS.data[gTS.p_read + 3] == 'A')
+					else if (IS_COMMAND('M','N','A'))
 					{
 						StartMapName();
 						gTS.p_read += 4;
 					}
-					else if (gTS.data[gTS.p_read + 1] == 'C' &&
-							 gTS.data[gTS.p_read + 2] == 'M' &&
-							 gTS.data[gTS.p_read + 3] == 'U')
+					else if (IS_COMMAND('S','O','U'))
 					{
 						int z = GetTextScriptNo(gTS.p_read + 4);
+						PlaySoundObject(z, 1);
+						gTS.p_read += 8;
+					}
+					else if (IS_COMMAND('C','M','U'))
+					{
+						int z = GetTextScriptNo(gTS.p_read + 4);
 						ChangeMusic(z);
 						gTS.p_read += 8;
 					}
-					else if (gTS.data[gTS.p_read + 1] == 'F' &&
-							 gTS.data[gTS.p_read + 2] == 'M' &&
-							 gTS.data[gTS.p_read + 3] == 'U')
+					else if (IS_COMMAND('F','M','U'))
 					{
 						SetOrganyaFadeout();
 						gTS.p_read += 4;
 					}
-					else if (gTS.data[gTS.p_read + 1] == 'R' &&
-							 gTS.data[gTS.p_read + 2] == 'M' &&
-							 gTS.data[gTS.p_read + 3] == 'U')
+					else if (IS_COMMAND('R','M','U'))
 					{
 						ReCallMusic();
 						gTS.p_read += 4;