shithub: cstory

Download patch

ref: 17b0b503a940ef0cfb70ed1506a3132c0b6146d6
parent: 0d8179e98c886cb82bc47845b3654dcaec71ebb6
author: cuckydev <[email protected]>
date: Sat Jan 26 14:40:25 EST 2019

got a bit of tsc done (still need to finish PutTextScript, then it's just commands as far as I know)

--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
 CXXFLAGS := -O3 -s
 FILENAME := release
 else
-CXXFLAGS := -O0 -g -mconsole
+CXXFLAGS := -O0 -g
 FILENAME := debug
 endif
 
@@ -18,6 +18,10 @@
 
 ifeq ($(FIX_BUGS), 1)
 CXXFLAGS += -DFIX_BUGS
+endif
+
+ifeq ($(CONSOLE), 1)
+CXXFLAGS += -mconsole
 endif
 
 CXXFLAGS += `sdl2-config --cflags` `pkg-config freetype2 --cflags`
--- a/src/Game.cpp
+++ b/src/Game.cpp
@@ -161,14 +161,14 @@
 		PutFade();
 		
 		//Update Text Script
-		//int tscRet = TextScriptProc();
-		//if (tscRet == 0)
-		//	return 0;
-		//if (tscRet == 2)
-		//	return 1;
+		int tscRet = TextScriptProc();
+		if (tscRet == 0)
+			return 0;
+		if (tscRet == 2)
+			return 1;
 	
 		PutMapName(false);
-		//PutTextScript();
+		PutTextScript();
 		PutFramePerSecound();
 		
 		if (!Flip_SystemTask())
@@ -440,92 +440,107 @@
 	InitFlags();
 	//InitBossLife();
 	
-	TransferStage(2, 94, 5, 6);
-	ChangeMusic(mus_MischievousRobot);
-	SetFrameTargetMyChar(16);
-	SetFrameMyChar();
-	
-	while (true)
+	if ((bContinue && LoadProfile(NULL)) || InitializeGame())
 	{
-		//Get pressed keys
-		GetTrg();
-		
-		//Escape menu
-		if (gKey & KEY_ESCAPE)
+		while (true)
 		{
-			int escRet = Call_Escape();
-			if (escRet == 0)
-				return 0;
-			if (escRet == 2)
-				return 1;
-		}
-		
-		if (swPlay & 1 && g_GameFlags & 1)
-		{
-			if (g_GameFlags & 2)
-				ActMyChar(true);
-			else
-				ActMyChar(false);
+			//Get pressed keys
+			GetTrg();
 			
-			//ActStar();
-			ActNpChar();
-			//ActBossChar();
-			//ActValueView();
-			ActBack();
-			ResetMyCharFlag();
-			HitMyCharMap();
-			//HitMyCharNpChar();
-			//HitMyCharBoss();
-			HitNpCharMap();
-			//HitBossMap();
-			//HitBulletMap();
-			//HitNpCharBullet();
-			//HitBossBullet();
-			//if (g_GameFlags & 2)
-			//	ShootBullet();
-			//ActBullet();
-			ActCaret();
-			MoveFrame3();
-			//ActFlash(frame_x, frame_y);
+			//Escape menu
+			if (gKey & KEY_ESCAPE)
+			{
+				int escRet = Call_Escape();
+				if (escRet == 0)
+					return 0;
+				if (escRet == 2)
+					return 1;
+			}
 			
-			if (g_GameFlags & 2)
-				AnimationMyChar(true);
-			else
-				AnimationMyChar(false);
+			if (swPlay & 1 && g_GameFlags & 1)
+			{
+				if (g_GameFlags & 2)
+					ActMyChar(true);
+				else
+					ActMyChar(false);
+				
+				//ActStar();
+				ActNpChar();
+				//ActBossChar();
+				//ActValueView();
+				ActBack();
+				ResetMyCharFlag();
+				HitMyCharMap();
+				//HitMyCharNpChar();
+				//HitMyCharBoss();
+				HitNpCharMap();
+				//HitBossMap();
+				//HitBulletMap();
+				//HitNpCharBullet();
+				//HitBossBullet();
+				//if (g_GameFlags & 2)
+				//	ShootBullet();
+				//ActBullet();
+				ActCaret();
+				MoveFrame3();
+				//ActFlash(frame_x, frame_y);
+				
+				if (g_GameFlags & 2)
+					AnimationMyChar(true);
+				else
+					AnimationMyChar(false);
+			}
+			
+			if (g_GameFlags & 8)
+			{
+				ActionCredit();
+				ActionIllust();
+				ActionStripper();
+			}
+			
+			ProcFade();
+			CortBox(&grcFull, 0x000020);
+			GetFramePosition(&frame_x, &frame_y);
+			PutBack(frame_x, frame_y);
+			PutStage_Back(frame_x, frame_y);
+			//PutBossChar(frame_x, frame_y);
+			PutNpChar(frame_x, frame_y);
+			//PutBullet(frame_x, frame_y);
+			PutMyChar(frame_x, frame_y);
+			//PutStar(frame_x, frame_y);
+			PutMapDataVector(frame_x, frame_y);
+			PutStage_Front(frame_x, frame_y);
+			PutFront(frame_x, frame_y);
+			//PutFlash();
+			PutCaret(frame_x, frame_y);
+			//PutValueView(frame_x, frame_y);
+			//PutBossLife();
+			PutFade();
+			
+			if (swPlay & 1)
+			{
+				int tscRet = TextScriptProc();
+				if (tscRet == 0)
+					return 0;
+				if (tscRet == 2)
+					return 1;
+			}
+			
+			PutMapName(false);
+			
+			if (g_GameFlags & 8)
+			{
+			  PutIllust();
+			  PutStripper();
+			}
+			
+			PutTextScript();
+			
+			PutFramePerSecound();
+			if (!Flip_SystemTask())
+			  break;
+			++gCounter;
 		}
-		
-		if (g_GameFlags & 8)
-		{
-			ActionCredit();
-			ActionIllust();
-			ActionStripper();
-		}
-		
-		ProcFade();
-		CortBox(&grcFull, 0x000020);
-		GetFramePosition(&frame_x, &frame_y);
-		PutBack(frame_x, frame_y);
-		PutStage_Back(frame_x, frame_y);
-		//PutBossChar(frame_x, frame_y);
-		PutNpChar(frame_x, frame_y);
-		//PutBullet(frame_x, frame_y);
-		PutMyChar(frame_x, frame_y);
-		//PutStar(frame_x, frame_y);
-		PutMapDataVector(frame_x, frame_y);
-		PutStage_Front(frame_x, frame_y);
-		PutFront(frame_x, frame_y);
-		//PutFlash();
-		PutCaret(frame_x, frame_y);
-		//PutValueView(frame_x, frame_y);
-		//PutBossLife();
-		PutFade();
-		
-		PutMapName(false);
-		
-		PutFramePerSecound();
-        if (!Flip_SystemTask())
-          break;
-        ++gCounter;
 	}
 	
 	return 0;
--- a/src/Profile.cpp
+++ b/src/Profile.cpp
@@ -6,6 +6,12 @@
 #include "CommonDefines.h"
 #include "Tags.h"
 #include "Profile.h"
+#include "Fade.h"
+#include "Flags.h"
+#include "MyChar.h"
+#include "Frame.h"
+#include "Stage.h"
+#include "Game.h"
 
 const char *gDefaultName = "Profile.dat";
 const char *gProfileCode = "Do041220";
@@ -20,5 +26,40 @@
 		return false;
 	
 	SDL_RWclose(fp);
+	return true;
+}
+
+bool SaveProfile(char *name)
+{
+	return false;
+}
+
+bool LoadProfile(char *name)
+{
+	return false;
+}
+
+bool InitializeGame()
+{
+	InitMyChar();
+	//gSelectedArms = 0;
+	//gSelectedItem = 0;
+	gCounter = 0;
+	//ClearArmsData();
+	//ClearItemData();
+	//ClearPermitStage();
+	//StartMapping();
+	InitFlags();
+	if (!TransferStage(13, 200, 10, 8))
+		return false;
+	ClearFade();
+	SetFrameMyChar();
+	SetFrameTargetMyChar(16);
+	//InitBossLife();
+	//CutNoise();
+	//ClearValueView();
+	//gCurlyShoot_wait = 0;
+	SetFadeMask();
+	SetFrameTargetMyChar(16);
 	return true;
 }
--- a/src/Profile.h
+++ b/src/Profile.h
@@ -2,3 +2,6 @@
 #include <stdint.h>
 
 bool IsProfile();
+bool SaveProfile(char *name);
+bool LoadProfile(char *name);
+bool InitializeGame();
--- a/src/Stage.cpp
+++ b/src/Stage.cpp
@@ -129,7 +129,7 @@
 		//Load map name
 		ReadyMapName(gTMT[no].name);
 		
-		//StartTextScript(w);
+		StartTextScript(w);
 		SetFrameMyChar();
 		//ClearBullet();
 		InitCaret();
--- a/src/TextScr.cpp
+++ b/src/TextScr.cpp
@@ -1,10 +1,22 @@
 #include <stdint.h>
 #include <string>
 
+#include <SDL_messagebox.h>
+#include "WindowsWrapper.h"
+
 #include "CommonDefines.h"
 #include "TextScr.h"
 #include "Draw.h"
 #include "Tags.h"
+#include "MyChar.h"
+#include "Fade.h"
+#include "Stage.h"
+#include "Flags.h"
+#include "MapName.h"
+#include "KeyControl.h"
+#include "NpChar.h"
+#include "Sound.h"
+#include "Organya.h"
 #include "Game.h"
 
 #define TSC_BUFFER_SIZE 0x5000
@@ -14,7 +26,7 @@
 int gNumberTextScript[4];
 char text[0x100];
 
-const RECT gRect_line = {0, 0, 216, 16};
+RECT gRect_line = {0, 0, 216, 16};
 
 //Initialize and end tsc
 bool InitTextScript2()
@@ -64,6 +76,32 @@
 	}
 }
 
+//Load generic .tsc
+bool LoadTextScript2(char *name)
+{
+	//Get path
+	char path[260];
+	sprintf(path, "%s/%s", gDataPath, name);
+	
+	//Open file
+	SDL_RWops *fp = SDL_RWFromFile(path, "rb");
+	if (!fp)
+		return false;
+	
+	//Read data
+	gTS.size = SDL_RWsize(fp);
+	fp->read(fp, gTS.data, 1, gTS.size);
+	gTS.data[gTS.size] = 0;
+	fp->close(fp);
+	
+	//Set path
+	strcpy(gTS.path, name);
+	
+	//Decrypt data
+	EncryptionBinaryData2((uint8_t*)gTS.data, gTS.size);
+	return true;
+}
+
 //Load stage .tsc
 bool LoadTextScript_Stage(char *name)
 {
@@ -77,7 +115,6 @@
 	
 	//Read Head.tsc
 	int head_size = SDL_RWsize(fp);
-	
 	fp->read(fp, gTS.data, 1, head_size);
 	EncryptionBinaryData2((uint8_t*)gTS.data, head_size);
 	gTS.data[head_size] = 0;
@@ -101,4 +138,738 @@
 	gTS.size = head_size + body_size;
 	strcpy(gTS.path, name);
 	return true;
+}
+
+//Get current path
+void GetTextScriptPath(char *path)
+{
+	strcpy(path, gTS.path);
+}
+
+//Get 4 digit number from TSC data
+int GetTextScriptNo(int a)
+{
+	return gTS.data[a + 3] - 48
+		+ 10 * gTS.data[a + 2] - 480
+		+ 100 * gTS.data[a + 1] - 4800
+		+ 1000 * gTS.data[a] - 48000;
+}
+
+//Start TSC event
+bool StartTextScript(int no)
+{
+	//Reset state
+	gTS.mode = 1;
+	g_GameFlags |= 5;
+	gTS.line = 0;
+	gTS.p_write = 0;
+	gTS.wait = 4;
+	gTS.flags = 0;
+	gTS.wait_beam = 0;
+	gTS.face = 0;
+	gTS.item = 0;
+	gTS.offsetY = 0;
+	
+	gMC.shock = 0;
+	
+	gTS.rcText = {WINDOW_WIDTH / 2 - 108, WINDOW_HEIGHT - 56, WINDOW_WIDTH + 108, WINDOW_HEIGHT - 8};
+	
+	//Clear text lines
+	for (int i = 0; i < 4; i++)
+	{
+		gTS.ypos_line[i] = 16 * i;
+		CortBox2(&gRect_line, 0x000000, i + 30);
+		memset(&text[i * 0x40], 0, 0x40);
+	}
+	
+	//Find where event starts
+	for (gTS.p_read = 0; ; gTS.p_read++)
+	{
+		//Check if we are still in the proper range
+		if (!gTS.data[gTS.p_read])
+			return false;
+		
+		//Check if we are at an event
+		if (gTS.data[gTS.p_read] != '#')
+			continue;
+		
+		//Check if this is our event
+		int event_no = GetTextScriptNo(++gTS.p_read);
+		
+		if (no == event_no)
+			break;
+		if (no < event_no)
+			return false;
+	}
+	
+	//Advance until new-line
+	while (gTS.data[gTS.p_read] != '\n')
+		++gTS.p_read;
+	++gTS.p_read;
+	
+	return true;
+}
+
+bool JumpTextScript(int no)
+{
+	//Set state
+	gTS.mode = 1;
+	g_GameFlags |= 4u;
+	gTS.line = 0;
+	gTS.p_write = 0;
+	gTS.wait = 4;
+	gTS.wait_beam = 0;
+	
+	//Clear text lines
+	for (int i = 0; i < 4; i++)
+	{
+		gTS.ypos_line[i] = 16 * i;
+		CortBox2(&gRect_line, 0x000000, i + 30);
+		memset(&text[i * 0x40], 0, 0x40);
+	}
+	
+	//Find where event starts
+	for (gTS.p_read = 0; ; gTS.p_read++)
+	{
+		//Check if we are still in the proper range
+		if (!gTS.data[gTS.p_read])
+			return false;
+		
+		//Check if we are at an event
+		if (gTS.data[gTS.p_read] != '#')
+			continue;
+		
+		//Check if this is our event
+		int event_no = GetTextScriptNo(++gTS.p_read);
+		
+		if (no == event_no)
+			break;
+		if (no < event_no)
+			return false;
+	}
+	
+	//Advance until new-line
+	while (gTS.data[gTS.p_read] != '\n')
+		++gTS.p_read;
+	++gTS.p_read;
+	
+	return true;
+}
+
+//End event
+void StopTextScript()
+{
+	//End TSC and reset flags
+	gTS.mode = 0;
+	g_GameFlags &= ~4;
+	g_GameFlags |= 3;
+	gTS.flags = 0;
+}
+
+//Prepare a new line
+void CheckNewLine()
+{
+	if (gTS.ypos_line[gTS.line % 4] == 48)
+	{
+		gTS.mode = 3;
+		g_GameFlags |= 4;
+		CortBox2(&gRect_line, 0, gTS.line % 4 + 30);
+		memset(&text[gTS.line % 4 * 0x40], 0, 0x40);
+	}
+}
+
+//Type a number into the text buffer
+void SetNumberTextScript(int index)
+{
+	//Get digit table
+	int table[3];
+	table[0] = 1000;
+	table[1] = 100;
+	table[2] = 10;
+	
+	//Get number to print
+	int a = gNumberTextScript[index];
+	int b;
+	
+	char str[5];
+	bool bZero = false;
+	int offset = 0;
+	
+	for (int i = 0; i < 3; i++)
+	{
+		if (a / table[i] || bZero)
+		{
+			//Do whatever the fuck this is
+			b = a / table[i];
+			str[offset] = b + 0x30;
+			bZero = true;
+			a -= b * table[i];
+			++offset;
+		}
+	}
+	
+	//Set last digit of string, and add null terminator
+	str[offset] = a + 0x30;
+	str[offset + 1] = 0;
+	
+	//Append number to line
+	PutText2(6 * gTS.p_write, 0, str, 0xFFFFFE, gTS.line % 4 + 30);
+	strcat(&text[gTS.line % 4 * 0x40], str);
+	
+	//Play sound and reset blinking cursor
+	PlaySoundObject(2, 1);
+	gTS.wait_beam = 0;
+	
+	//Check if should move to next line (prevent a memory overflow, come on guys, this isn't a leftover of pixel trying to make text wrapping)
+	gTS.p_write += strlen(str);
+	
+	if (gTS.p_write > 34)
+	{
+		gTS.p_write = 0;
+		gTS.line++;
+		CheckNewLine();
+	}
+}
+
+//Clear text lines
+void ClearTextLine()
+{
+	gTS.line = 0;
+	gTS.p_write = 0;
+	gTS.offsetY = 0;
+	
+	for (int i = 0; i < 4; i++)
+	{
+		gTS.ypos_line[i] = 16 * i;
+		CortBox2(&gRect_line, 0x000000, i + 30);
+		memset(&text[i * 0x40], 0, 0x40);
+	}
+}
+
+//Draw textbox and whatever else
+void PutTextScript()
+{
+	if (gTS.mode && (gTS.flags & 1))
+	{
+		//Set textbox position
+		if (gTS.flags & 0x20)
+		{
+			gTS.rcText.top = 32;
+			gTS.rcText.bottom = 80;
+		}
+		else
+		{
+			gTS.rcText.top = WINDOW_HEIGHT - 56;
+			gTS.rcText.bottom = WINDOW_HEIGHT - 8;
+		}
+		
+		//Draw textbox
+		if (gTS.flags & 2)
+		{
+			RECT rcFrame1 = {0, 0, 244, 8};
+			RECT rcFrame2 = {0, 8, 244, 16};
+			RECT rcFrame3 = {0, 16, 244, 24};
+			
+			PutBitmap3(&grcFull, gTS.rcText.left - 14, gTS.rcText.top - 10, &rcFrame1, 26);
+			int i;
+			for (i = 1; i < 7; i++)
+				PutBitmap3(&grcFull, gTS.rcText.left - 14, 8 * i + gTS.rcText.top - 10, &rcFrame2, 26);
+			PutBitmap3(&grcFull, gTS.rcText.left - 14, 8 * i + gTS.rcText.top - 10, &rcFrame3, 26);
+		}
+		
+		//Draw face picture
+		RECT rcFace;
+		rcFace.left = 48 * (gTS.face % 6);
+		rcFace.top = 48 * (gTS.face / 6);
+		rcFace.right = 48 * (gTS.face % 6) + 48;
+		rcFace.bottom = 48 * (gTS.face / 6) + 48;
+		
+		if (gTS.face_x < (gTS.rcText.left << 9))
+			gTS.face_x += 0x1000;
+		PutBitmap3(&gTS.rcText, gTS.face_x / 0x200, gTS.rcText.top - 3, &rcFace, 27);
+		
+		//Draw text
+		int text_offset;
+		if (gTS.face)
+			text_offset = 56;
+		else
+			text_offset = 0;
+		
+		for (int i = 0; i < 4; i++)
+			PutBitmap3(&gTS.rcText, text_offset + gTS.rcText.left, gTS.offsetY + gTS.ypos_line[i] + gTS.rcText.top, &gRect_line, i + 30);
+		
+		//Draw NOD cursor
+		if ((gTS.wait_beam++ % 20 > 12) && gTS.mode == 2)
+		{
+			RECT rect;
+			rect.left = gTS.rcText.left + text_offset + 6 * gTS.p_write;
+			rect.top = gTS.rcText.top + gTS.ypos_line[gTS.line % 4] + gTS.offsetY;
+			rect.right = rect.left + 5;
+			rect.bottom = rect.top + 11;
+			CortBox(&rect, 0xFFFFFE);
+		}
+	}
+}
+
+//Parse TSC
+int TextScriptProc()
+{
+	RECT rcSymbol = {64, 48, 72, 56};
+	
+	bool bExit;
+	
+	switch (gTS.mode)
+	{
+		case 1: //PARSE
+			//Type out (faster if ok or cancel are held)
+			++gTS.wait;
+			
+			if (!(g_GameFlags & 2) && (gKeyCancel | gKeyOk) & gKey)
+				gTS.wait += 4;
+			
+			if (gTS.wait < 4)
+				break;
+			
+			gTS.wait = 0;
+			
+			//Parsing time
+			bExit = false;
+			
+			while (!bExit)
+			{
+				if (gTS.data[gTS.p_read] != '<')
+				{
+					if (gTS.data[gTS.p_read] == '\r')
+					{
+						//Go to new-line
+						gTS.p_read += 2;
+						gTS.p_write = 0;
+						
+						if (gTS.flags & 1)
+						{
+							++gTS.line;
+							CheckNewLine();
+						}
+					}
+					else if (gTS.flags & 0x10)
+					{
+						//SAT/CAT/TUR printing
+						int x;
+						for (x = gTS.p_read; ; x++)
+						{
+							//Break if reaches command, or new-line
+							if (gTS.data[x] == '<' || gTS.data[x] == '\r')
+								break;
+							//Skip if SHIFT-JIS
+							if (gTS.data[x] & 0x80)
+								++x;
+						}
+						
+						//Get text to copy
+						char str[72];
+						int length = x - gTS.p_read;
+						memcpy(str, &gTS.data[gTS.p_read], length);
+						str[length] = 0;
+						
+						gTS.p_write = x;
+						
+						//Print text
+						PutText2(0, 0, str, 0xFFFFFE, gTS.line % 4 + 30);
+						sprintf(&text[gTS.line % 4 * 0x40], str);
+						
+						//Check if should move to next line (prevent a memory overflow, come on guys, this isn't a leftover of pixel trying to make text wrapping)
+						gTS.p_read += length;
+
+						if (gTS.p_write > 34)
+							CheckNewLine();
+						
+						bExit = true;
+					}
+					else
+					{
+						//Get text to print
+						char c[3];
+						c[0] = gTS.data[gTS.p_read];
+						
+						if (!(c[0] & 0x80))
+						{
+							c[1] = 0;
+						}
+						else
+						{
+							c[1] = gTS.data[gTS.p_read + 1];
+							c[2] = 0;
+						}
+						
+						//Print text
+						if (c[0] == '=')
+						{
+							Surface2Surface(6 * gTS.p_write, 2, &rcSymbol, gTS.line % 4 + 30, 26);
+						}
+						else
+						{
+							PutText2(6 * gTS.p_write, 0, c, 0xFFFFFE, gTS.line % 4 + 30);
+						}
+						
+						strcat(&text[gTS.line % 4 * 0x40], c);
+						PlaySoundObject(2, 1);
+						gTS.wait_beam = 0;
+						
+						//Offset read and write positions
+						if (!(c[0] & 0x80))
+						{
+							gTS.p_read++;
+							gTS.p_write++;
+						}
+						else
+						{
+							gTS.p_read += 2;
+							gTS.p_write += 2;
+						}
+						
+						if (gTS.p_write > 34)
+						{
+							CheckNewLine();
+							gTS.p_write = 0;
+							++gTS.line;
+							CheckNewLine();
+						}
+						
+						bExit = true;
+					}
+				}
+				else
+				{
+					if (gTS.data[gTS.p_read + 1] == 'E' &&
+						gTS.data[gTS.p_read + 2] == 'N' &&
+						gTS.data[gTS.p_read + 3] == 'D')
+					{
+						gTS.mode = 0;
+						gMC.cond &= ~1;
+						g_GameFlags |= 3;
+						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')
+					{
+						int z = GetTextScriptNo(gTS.p_read + 4);
+						int w = GetTextScriptNo(gTS.p_read + 9);
+						int x = GetTextScriptNo(gTS.p_read + 14);
+						int y = GetTextScriptNo(gTS.p_read + 19);
+						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] == '+')
+					{
+						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] == '-')
+					{
+						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] == '+')
+					{
+						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] == '-')
+					{
+						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')
+					{
+						g_GameFlags &= ~2;
+						g_GameFlags |= 1;
+						gMC.up = false;
+						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')
+					{
+						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')
+					{
+						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')
+					{
+						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')
+					{
+						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')
+					{
+						ClearTextLine();
+						gTS.flags |= 0x03;
+						gTS.flags &= ~0x30;
+						if (gTS.flags & 0x40)
+							gTS.flags |= 0x10;
+						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')
+					{
+						ClearTextLine();
+						gTS.flags |= 0x21;
+						gTS.flags &= ~0x12;
+						if (gTS.flags & 0x40)
+							gTS.flags |= 0x10;
+						gTS.face = 0;
+						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')
+					{
+						ClearTextLine();
+						gTS.flags |= 0x23;
+						gTS.flags &= ~0x10;
+						if (gTS.flags & 0x40)
+							gTS.flags |= 0x10;
+						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')
+					{
+						gTS.mode = 4;
+						gTS.wait_next = GetTextScriptNo(gTS.p_read + 4);
+						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')
+					{
+						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')
+					{
+						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')
+					{
+						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')
+					{
+						int x = GetTextScriptNo(gTS.p_read + 4);
+						int z = GetTextScriptNo(gTS.p_read + 9);
+						
+						if (GetNPCFlag(x))
+							JumpTextScript(z);
+						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')
+					{
+						int x = GetTextScriptNo(gTS.p_read + 4);
+						int z = GetTextScriptNo(gTS.p_read + 9);
+						
+						if (GetSkipFlag(x))
+							JumpTextScript(z);
+						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')
+					{
+						int z = GetTextScriptNo(gTS.p_read + 4);
+						StartFadeIn(z);
+						gTS.mode = 5;
+						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')
+					{
+						int z = GetTextScriptNo(gTS.p_read + 4);
+						StartFadeOut(z);
+						gTS.mode = 5;
+						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')
+					{
+						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')
+					{
+						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')
+					{
+						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')
+					{
+						ReCallMusic();
+						gTS.p_read += 4;
+					}
+					else
+					{
+						printf("Unimplemented command: <%c%c%c\n", (char)gTS.data[gTS.p_read + 1], (char)gTS.data[gTS.p_read + 2], (char)gTS.data[gTS.p_read + 3]);
+						gTS.p_read += 4;
+						return 1;
+					}
+				}
+			}
+			break;
+			
+		case 2: //NOD
+			if ((gKeyCancel | gKeyOk) & gKeyTrg)
+				gTS.mode = 1;
+			break;
+			
+		case 3: //NEW LINE
+			for (int i = 0; i < 4; i++)
+			{
+				gTS.ypos_line[i] -= 4;
+				
+				if (!gTS.ypos_line[i])
+					gTS.mode = 1;
+				
+				if (gTS.ypos_line[i] == -16)
+					gTS.ypos_line[i] = 48;
+			}
+			break;
+			
+		case 4: //WAI
+			if (gTS.wait_next != 9999)
+			{
+				if (gTS.wait != 9999)
+					++gTS.wait;
+				
+				if (gTS.wait >= gTS.wait_next)
+				{
+					gTS.mode = 1;
+					gTS.wait_beam = 0;
+				}
+			}
+			break;
+			
+		case 5: //FAI/FAO
+			if (!GetFadeActive())
+			{
+				gTS.mode = 1;
+				gTS.wait_beam = 0;
+			}
+			break;
+		case 7: //WAS
+			if (gMC.flag & 8)
+			{
+				gTS.mode = 1;
+				gTS.wait_beam = 0;
+			}
+			break;
+		case 6: //YNJ
+			if (gTS.wait >= 16)
+			{
+				//Select option
+				if (gKeyTrg & gKeyOk)
+				{
+					PlaySoundObject(18, 1);
+					
+					if (gTS.select == 1)
+					{
+						JumpTextScript(gTS.next_event);
+					}
+					else
+					{
+						gTS.mode = 1;
+						gTS.wait_beam = 0;
+					}
+				}
+				//Yes
+				else if (gKeyTrg & gKeyLeft)
+				{
+					gTS.select = 0;
+					PlaySoundObject(1, 1);
+				}
+				//No
+				else if (gKeyTrg & gKeyRight)
+				{
+					gTS.select = 1;
+					PlaySoundObject(1, 1);
+				}
+			}
+			else
+			{
+				gTS.wait++;
+			}
+			break;
+	}
+	
+	if (gTS.mode)
+		g_GameFlags |= 4;
+	else
+		g_GameFlags &= ~4;
+	return 1;
 }
--- a/src/TextScr.h
+++ b/src/TextScr.h
@@ -19,8 +19,8 @@
 	char flags;
 	
 	//Current positions (read position in buffer, x position in line)
-	int p_read;
-	int p_write;
+	unsigned int p_read;
+	unsigned int p_write;
 	
 	//Current line to write to
 	int line;
@@ -47,7 +47,7 @@
 	//Text rect
 	RECT rcText;
 	
-	//???
+	//..?
 	int offsetY;
 	
 	//NOD cursor blink
@@ -57,4 +57,9 @@
 bool InitTextScript2();
 void EndTextScript();
 void EncryptionBinaryData2(uint8_t *pData, int size);
+bool LoadTextScript2(char *name);
 bool LoadTextScript_Stage(char *name);
+void GetTextScriptPath(char *path);
+bool StartTextScript(int no);
+void PutTextScript();
+int TextScriptProc();
\ No newline at end of file