shithub: cstory

Download patch

ref: c44186d93a83aa912b96347fbefa606c28bee8c9
parent: 8942c6cc481582905bade27799dd2abe330ee34e
author: Clownacy <Clownacy@users.noreply.github.com>
date: Fri Feb 15 15:33:08 EST 2019

Ditched SDL's file IO for stdio and our own convenience functions

ASM-accurate file stuff can come later.

--- a/Makefile
+++ b/Makefile
@@ -65,6 +65,7 @@
 	Ending \
 	Escape \
 	Fade \
+	File \
 	Flags \
 	Flash \
 	Font \
--- a/src/Config.cpp
+++ b/src/Config.cpp
@@ -5,11 +5,11 @@
 #include <stdint.h>
 #include <string.h>
 
-#include <SDL_rwops.h>
 #include "WindowsWrapper.h"
 
 #include "Tags.h"
 #include "Config.h"
+#include "File.h"
 
 bool LoadConfigData(CONFIG *conf)
 {
@@ -21,30 +21,30 @@
 	sprintf(path, "%s/%s", gModulePath, "Config.dat");
 	
 	//Open file
-	SDL_RWops *fp = SDL_RWFromFile(path, "rb");
-	if (!fp)
+	FILE *fp = fopen(path, "rb");
+	if (fp == NULL)
 		return false;
 	
-	//Read data (we're using SDL_RWops so we can load it with the specific endianness expected)
+	//Read data
 	//Read the version id and font name
-	fp->read(fp, conf->proof, sizeof(conf->proof), 1);
-	fp->read(fp, conf->font_name, sizeof(conf->font_name), 1);
+	fread(conf->proof, sizeof(conf->proof), 1, fp);
+	fread(conf->font_name, sizeof(conf->font_name), 1, fp);
 	
 	//Read control settings
-	conf->move_button_mode = SDL_ReadLE32(fp);
-	conf->attack_button_mode = SDL_ReadLE32(fp);
-	conf->ok_button_mode = SDL_ReadLE32(fp);
+	conf->move_button_mode = File_ReadLE32(fp);
+	conf->attack_button_mode = File_ReadLE32(fp);
+	conf->ok_button_mode = File_ReadLE32(fp);
 	
 	//Read display mode (320x240, 640x480, 24-bit fullscreen, 32-bit fullscreen) TODO: add more things?
-	conf->display_mode = SDL_ReadLE32(fp);
+	conf->display_mode = File_ReadLE32(fp);
 	
 	//Read joystick configuration (if enabled, and mappings)
-	conf->bJoystick = SDL_ReadLE32(fp);
+	conf->bJoystick = File_ReadLE32(fp);
 	for (int button = 0; button < 8; button++)
-		conf->joystick_button[button] = SDL_ReadLE32(fp);
+		conf->joystick_button[button] = File_ReadLE32(fp);
 	
 	//Close file
-	fp->close(fp);
+	fclose(fp);
 	
 	//Check if version is correct, return that it succeeded
 	if (!strcmp(conf->proof, "DOUKUTSU20041206"))
--- a/src/Draw.h
+++ b/src/Draw.h
@@ -56,7 +56,6 @@
 bool StartDirectDraw(int lMagnification, int lColourDepth);
 void EndDirectDraw();
 void ReleaseSurface(int s);
-bool MakeSurface(SDL_RWops *rw, int surf_no);
 bool MakeSurface_File(const char *name, int surf_no);
 bool MakeSurface_Resource(const char *res, int surf_no);
 bool ReloadBitmap_File(const char *name, int surf_no);
--- a/src/Ending.cpp
+++ b/src/Ending.cpp
@@ -1,7 +1,6 @@
 #include <stdint.h>
 #include <string>
 
-#include <SDL_rwops.h>
 #include "WindowsWrapper.h"
 
 #include "Tags.h"
@@ -163,25 +162,31 @@
 	//Open file
 	char path[PATH_LENGTH];
 	sprintf(path, "%s/%s", gDataPath, "Credit.tsc");
-	
-	SDL_RWops *fp = SDL_RWFromFile(path, "rb");
-	if (!fp)
-	{
-		printf("Couldn't open %s", path);
+
+	Credit.size = GetFileSizeLong(path);
+	if (Credit.size == -1)
 		return false;
-	}
-	
+
 	//Allcoate buffer data
-	Credit.size = SDL_RWsize(fp);
-	
 	Credit.pData = (char*)malloc(Credit.size);
-	if (!Credit.pData)
+	if (Credit.pData == NULL)
 		return false;
-	
+
+	FILE *fp = fopen(path, "rb");
+	if (fp == NULL)
+	{
+		printf("Couldn't open %s", path);
+		return false;
+	}
+
 	//Read data
-	SDL_RWread(fp, Credit.pData, 1, Credit.size);
-	SDL_RWclose(fp);
+	fread(Credit.pData, 1, Credit.size, fp);
 	EncryptionBinaryData2((uint8_t*)Credit.pData, Credit.size);
+
+#ifdef FIX_BUGS
+	// The original game forgot to close the file
+	fclose(fp);
+#endif
 	
 	//Reset credits
 	Credit.offset = 0;
@@ -192,6 +197,7 @@
 	
 	//Modify cliprect
 	grcGame.left = WINDOW_WIDTH / 2;
+	// These three are non-vanilla: for wide/tallscreen support
 	grcGame.right = ((WINDOW_WIDTH - 320) / 2) + 320;
 	grcGame.top = (WINDOW_HEIGHT - 240) / 2;
 	grcGame.bottom = ((WINDOW_HEIGHT - 240) / 2) + 240;
@@ -198,10 +204,8 @@
 	
 	//Reload casts
 	if (!ReloadBitmap_File("casts", SURFACE_ID_CASTS))
-	{
 		return false;
-	}
-	
+
 	//Clear casts
 	memset(Strip, 0, sizeof(Strip));
 	return true;
--- /dev/null
+++ b/src/File.cpp
@@ -1,0 +1,98 @@
+#include "File.h"
+
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+long LoadFileToMemory(const char *file_path, unsigned char **file_buffer)
+{
+	long returned_size = -1;
+
+	FILE *file = fopen(file_path, "rb");
+
+	if (file != NULL)
+	{
+		if (!fseek(file, 0, SEEK_END))
+		{
+			const long file_size = ftell(file);
+
+			if (file_size >= 0)
+			{
+				rewind(file);
+				*file_buffer = (unsigned char*)malloc(file_size);
+
+				if (*file_buffer != NULL)
+				{
+					if (fread(*file_buffer, file_size, 1, file) == 1)
+						returned_size = file_size;
+
+					free(file_buffer);
+				}
+			}
+		}
+
+		fclose(file);
+	}
+
+	return returned_size;
+}
+
+unsigned short File_ReadBE16(FILE *stream)
+{
+	unsigned char bytes[2];
+
+	fread(bytes, 2, 1, stream);
+
+	return (bytes[0] << 8) | bytes[1];
+}
+
+unsigned long File_ReadBE32(FILE *stream)
+{
+	unsigned char bytes[4];
+
+	fread(bytes, 4, 1, stream);
+
+	return (bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3];
+}
+
+unsigned short File_ReadLE16(FILE *stream)
+{
+	unsigned char bytes[2];
+
+	fread(bytes, 2, 1, stream);
+
+	return (bytes[1] << 8) | bytes[0];
+}
+
+unsigned long File_ReadLE32(FILE *stream)
+{
+	unsigned char bytes[4];
+
+	fread(bytes, 4, 1, stream);
+
+	return (bytes[3] << 24) | (bytes[2] << 16) | (bytes[1] << 8) | bytes[0];
+}
+
+void File_WriteBE16(unsigned short value, FILE *stream)
+{
+	for (unsigned int i = 2; i-- != 0;)
+		fputc(value >> (8 * i), stream);
+}
+
+void File_WriteBE32(unsigned long value, FILE *stream)
+{
+	for (unsigned int i = 4; i-- != 0;)
+		fputc(value >> (8 * i), stream);
+}
+
+void File_WriteLE16(unsigned short value, FILE *stream)
+{
+	for (unsigned int i = 0; i < 2; ++i)
+		fputc(value >> (8 * i), stream);
+}
+
+void File_WriteLE32(unsigned long value, FILE *stream)
+{
+	for (unsigned int i = 0; i < 4; ++i)
+		fputc(value >> (8 * i), stream);
+}
--- /dev/null
+++ b/src/File.h
@@ -1,0 +1,15 @@
+#pragma once
+
+#include <stdio.h>
+
+long LoadFileToMemory(const char *file_path, unsigned char **file_buffer);
+
+unsigned short File_ReadBE16(FILE *stream);
+unsigned long File_ReadBE32(FILE *stream);
+unsigned short File_ReadLE16(FILE *stream);
+unsigned long File_ReadLE32(FILE *stream);
+
+void File_WriteBE16(unsigned short value, FILE *stream);
+void File_WriteBE32(unsigned long value, FILE *stream);
+void File_WriteLE16(unsigned short value, FILE *stream);
+void File_WriteLE32(unsigned long value, FILE *stream);
--- a/src/Font.cpp
+++ b/src/Font.cpp
@@ -17,6 +17,8 @@
 
 #include "SDL.h"
 
+#include "File.h"
+
 // Uncomment for that authentic pre-Windows Vista feel
 //#define DISABLE_FONT_ANTIALIASING
 
@@ -156,19 +158,12 @@
 {
 	FontObject *font_object = NULL;
 
-	FILE *file = fopen(font_filename, "rb");
+	unsigned char *file_buffer;
+	const long file_size = LoadFileToMemory(font_filename, &file_buffer);
 
-	if (file != NULL)
+	if (file_size != -1)
 	{
-		fseek(file, 0, SEEK_END);
-		const size_t file_size = ftell(file);
-		rewind(file);
-		unsigned char *file_buffer = (unsigned char*)malloc(file_size);
-		fread(file_buffer, 1, file_size, file);
-		fclose(file);
-
 		font_object = LoadFontFromData(file_buffer, file_size, cell_width, cell_height);
-
 		free(file_buffer);
 	}
 
--- a/src/Generic.cpp
+++ b/src/Generic.cpp
@@ -13,6 +13,21 @@
 	return true;
 }
 
+long GetFileSizeLong(const char *path)
+{
+	long len = -1;
+
+	FILE *fp = fopen(path, "rb");
+	if (fp != NULL)
+	{
+		fseek(fp, 0, SEEK_END);
+		len = ftell(fp);
+		fclose(fp);
+	}
+
+	return len;
+}
+
 bool CheckFileExists(const char *name)
 {
 	char path[PATH_LENGTH];
--- a/src/Generic.h
+++ b/src/Generic.h
@@ -2,5 +2,6 @@
 #include <stdint.h>
 
 bool GetCompileVersion(int *v1, int *v2, int *v3, int *v4);
+long GetFileSizeLong(const char *path);
 bool CheckFileExists(const char *name);
 bool IsShiftJIS(uint8_t c);
--- a/src/Map.cpp
+++ b/src/Map.cpp
@@ -1,7 +1,7 @@
+#include <stddef.h>
 #include <stdint.h>
 #include <string>
 
-#include <SDL_rwops.h>
 #include "WindowsWrapper.h"
 
 #include "CommonDefines.h"
@@ -9,6 +9,7 @@
 #include "Tags.h"
 #include "Draw.h"
 #include "NpChar.h"
+#include "File.h"
 
 #define PXM_BUFFER_SIZE 0x4B000
 
@@ -27,39 +28,39 @@
 	sprintf(path, "%s/%s", gDataPath, path_map);
 	
 	//Open file
-	SDL_RWops *fp = SDL_RWFromFile(path, "rb");
-	if (!fp)
+	FILE *fp = fopen(path, "rb");
+	if (fp == NULL)
 		return false;
 	
 	//Make sure file begins with "PXM"
 	char check[3];
-	fp->read(fp, check, 1, 3);
+	fread(check, 1, 3, fp);
 	
 	if (!memcmp(check, "PXM", 3))
 	{
 		uint8_t nul;
-		fp->read(fp, &nul, 1, 1);
+		fread(&nul, 1, 1, fp);
 		
 		//Get width and height
-		gMap.width = SDL_ReadLE16(fp);
-		gMap.length = SDL_ReadLE16(fp);
+		gMap.width = File_ReadLE16(fp);
+		gMap.length = File_ReadLE16(fp);
 		
 		if (gMap.data)
 		{
 			//Read tiledata
-			fp->read(fp, gMap.data, 1, gMap.length * gMap.width);
-			SDL_RWclose(fp);
+			fread(gMap.data, 1, gMap.length * gMap.width, fp);
+			fclose(fp);
 			return true;
 		}
 		else
 		{
-			SDL_RWclose(fp);
+			fclose(fp);
 			return false;
 		}
 	}
 	else
 	{
-		SDL_RWclose(fp);
+		fclose(fp);
 		return false;
 	}
 	
@@ -72,13 +73,13 @@
 	char path[260];
 	sprintf(path, "%s/%s", gDataPath, path_atrb);
 	
-	SDL_RWops *fp = SDL_RWFromFile(path, "rb");
-	if (!fp)
+	FILE *fp = fopen(path, "rb");
+	if (fp == NULL)
 		return false;
 	
 	//Read data
-	fp->read(fp, gMap.atrb, 1, 0x100);
-	SDL_RWclose(fp);
+	fread(gMap.atrb, 1, 0x100, fp);
+	fclose(fp);
 	return true;
 }
 
--- a/src/MycParam.cpp
+++ b/src/MycParam.cpp
@@ -10,6 +10,7 @@
 #include "Game.h"
 #include "Draw.h"
 #include "Caret.h"
+#include "File.h"
 
 ARMS_LEVEL gArmsLevelTable[14] =
 {
@@ -394,19 +395,19 @@
 	char path[PATH_LENGTH];
 	sprintf(path, "%s/290.rec", gModulePath);
 	
-	SDL_RWops *fp = SDL_RWFromFile(path, "rb");
+	FILE *fp = fopen(path, "rb");
 	if (fp)
 	{
 		//Read data
-		rec.counter[0] = SDL_ReadLE32(fp);
-		rec.counter[1] = SDL_ReadLE32(fp);
-		rec.counter[2] = SDL_ReadLE32(fp);
-		rec.counter[3] = SDL_ReadLE32(fp);
-		rec.random[0] = SDL_ReadU8(fp);
-		rec.random[1] = SDL_ReadU8(fp);
-		rec.random[2] = SDL_ReadU8(fp);
-		rec.random[3] = SDL_ReadU8(fp);
-		SDL_RWclose(fp);
+		rec.counter[0] = File_ReadLE32(fp);
+		rec.counter[1] = File_ReadLE32(fp);
+		rec.counter[2] = File_ReadLE32(fp);
+		rec.counter[3] = File_ReadLE32(fp);
+		rec.random[0] = fgetc(fp);
+		rec.random[1] = fgetc(fp);
+		rec.random[2] = fgetc(fp);
+		rec.random[3] = fgetc(fp);
+		fclose(fp);
 
 		uint8_t *p = (uint8_t*)&rec.counter[0];
 		p[0] -= (SDL_BYTEORDER == SDL_LIL_ENDIAN) ? (rec.random[0]) : (rec.random[0] >> 1);
@@ -432,18 +433,18 @@
 		p[3] += (SDL_BYTEORDER == SDL_LIL_ENDIAN) ? (rec.random[i] >> 1) : (rec.random[i]);
 	}
 	
-	fp = SDL_RWFromFile(path, "wb");
-	if (!fp)
+	fp = fopen(path, "wb");
+	if (fp == NULL)
 		return false;
-	SDL_WriteLE32(fp, rec.counter[0]);
-	SDL_WriteLE32(fp, rec.counter[1]);
-	SDL_WriteLE32(fp, rec.counter[2]);
-	SDL_WriteLE32(fp, rec.counter[3]);
-	SDL_WriteU8(fp, rec.random[0]);
-	SDL_WriteU8(fp, rec.random[1]);
-	SDL_WriteU8(fp, rec.random[2]);
-	SDL_WriteU8(fp, rec.random[3]);
-	SDL_RWclose(fp);
+	File_WriteLE32(rec.counter[0], fp);
+	File_WriteLE32(rec.counter[1], fp);
+	File_WriteLE32(rec.counter[2], fp);
+	File_WriteLE32(rec.counter[3], fp);
+	fputc(rec.random[0], fp);
+	fputc(rec.random[1], fp);
+	fputc(rec.random[2], fp);
+	fputc(rec.random[3], fp);
+	fclose(fp);
 	return true;
 }
 
@@ -453,7 +454,7 @@
 	char path[PATH_LENGTH];
 	sprintf(path, "%s/290.rec", gModulePath);
 	
-	SDL_RWops *fp = SDL_RWFromFile(path, "rb");
+	FILE *fp = fopen(path, "rb");
 	if (!fp)
 		return 0;
 	
@@ -460,15 +461,15 @@
 	REC rec;
 	
 	//Read data
-	rec.counter[0] = SDL_ReadLE32(fp);
-	rec.counter[1] = SDL_ReadLE32(fp);
-	rec.counter[2] = SDL_ReadLE32(fp);
-	rec.counter[3] = SDL_ReadLE32(fp);
-	rec.random[0] = SDL_ReadU8(fp);
-	rec.random[1] = SDL_ReadU8(fp);
-	rec.random[2] = SDL_ReadU8(fp);
-	rec.random[3] = SDL_ReadU8(fp);
-	SDL_RWclose(fp);
+	rec.counter[0] = File_ReadLE32(fp);
+	rec.counter[1] = File_ReadLE32(fp);
+	rec.counter[2] = File_ReadLE32(fp);
+	rec.counter[3] = File_ReadLE32(fp);
+	rec.random[0] = fgetc(fp);
+	rec.random[1] = fgetc(fp);
+	rec.random[2] = fgetc(fp);
+	rec.random[3] = fgetc(fp);
+	fclose(fp);
 	
 	//Decode from checksum
 	for (int i = 0; i < 4; i++)
--- a/src/NpChar.cpp
+++ b/src/NpChar.cpp
@@ -1,6 +1,7 @@
+#include <stddef.h>
 #include <stdint.h>
+#include <stdio.h>
 
-#include <SDL_rwops.h>
 #include "WindowsWrapper.h"
 
 #include "CommonDefines.h"
@@ -15,6 +16,7 @@
 #include "ValueView.h"
 #include "NpcTbl.h"
 #include "Draw.h"
+#include "File.h"
 
 NPCHAR gNPC[NPC_MAX];
 int gCurlyShoot_wait;
@@ -54,18 +56,24 @@
 	char path[PATH_LENGTH];
 	sprintf(path, "%s/%s", gDataPath, path_event);
 
-	SDL_RWops *fp = SDL_RWFromFile(path, "rb");
-	if (!fp)
+	FILE *fp = fopen(path, "rb");
+	if (fp == NULL)
 		return false;
 
 	//Read "PXE" check
 	char code[4];
-	fp->read(fp, code, 1, 4);
+	fread(code, 1, 4, fp);
 	if (memcmp(code, gPassPixEve, 3))
+	{
+#ifdef FIX_BUGS
+		// The original game forgot to close the file here
+		fclose(fp);
+#endif
 		return false;
+	}
 
 	//Get amount of NPCs
-	int count = SDL_ReadLE32(fp);
+	int count = File_ReadLE32(fp);
 
 	//Load NPCs
 	memset(gNPC, 0, sizeof(gNPC));
@@ -75,12 +83,12 @@
 	{
 		//Get data from file
 		EVENT eve;
-		eve.x = SDL_ReadLE16(fp);
-		eve.y = SDL_ReadLE16(fp);
-		eve.code_flag = SDL_ReadLE16(fp);
-		eve.code_event = SDL_ReadLE16(fp);
-		eve.code_char = SDL_ReadLE16(fp);
-		eve.bits = SDL_ReadLE16(fp);
+		eve.x = File_ReadLE16(fp);
+		eve.y = File_ReadLE16(fp);
+		eve.code_flag = File_ReadLE16(fp);
+		eve.code_event = File_ReadLE16(fp);
+		eve.code_char = File_ReadLE16(fp);
+		eve.bits = File_ReadLE16(fp);
 
 		//Set NPC parameters
 		if (eve.bits & npc_altDir)
@@ -117,6 +125,7 @@
 		n++;
 	}
 
+	fclose(fp);
 	return true;
 }
 
--- a/src/NpcTbl.cpp
+++ b/src/NpcTbl.cpp
@@ -1,49 +1,52 @@
-#include <string>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 
-#include <SDL_rwops.h>
-
 #include "NpcTbl.h"
 #include "NpcAct.h"
+#include "File.h"
+#include "Generic.h"
 
 NPC_TABLE *gNpcTable;
 
 bool LoadNpcTable(const char *path)
 {
-	SDL_RWops *fp = SDL_RWFromFile(path, "rb");
-
-	if (fp == nullptr)
-	{
-		printf("LoadNpcTable failed\nSDL Error: %s\n", SDL_GetError());
+	const long size = GetFileSizeLong(path);
+	if (size == -1)
 		return false;
-	}
 
-	const size_t tblSize = SDL_RWsize(fp);
+	const long num = size / 0x18;
 
-	const size_t npcCount = tblSize / 0x18;
-	gNpcTable = (NPC_TABLE*)malloc(npcCount * sizeof(NPC_TABLE));
+	gNpcTable = (NPC_TABLE*)malloc(num * sizeof(NPC_TABLE));
+	if (gNpcTable == NULL)
+		return false;
 
-	for (size_t i = 0; i < npcCount; i++) //bits
-		gNpcTable[i].bits = SDL_ReadLE16(fp);
-	for (size_t i = 0; i < npcCount; i++) //life
-		gNpcTable[i].life = SDL_ReadLE16(fp);
-	for (size_t i = 0; i < npcCount; i++) //surf
-		fp->read(fp, &gNpcTable[i].surf, 1, 1);
-	for (size_t i = 0; i < npcCount; i++) //destroy_voice
-		fp->read(fp, &gNpcTable[i].destroy_voice, 1, 1);
-	for (size_t i = 0; i < npcCount; i++) //hit_voice
-		fp->read(fp, &gNpcTable[i].hit_voice, 1, 1);
-	for (size_t i = 0; i < npcCount; i++) //size
-		fp->read(fp, &gNpcTable[i].size, 1, 1);
-	for (size_t i = 0; i < npcCount; i++) //exp
-		gNpcTable[i].exp = SDL_ReadLE32(fp);
-	for (size_t i = 0; i < npcCount; i++) //damage
-		gNpcTable[i].damage = SDL_ReadLE32(fp);
-	for (size_t i = 0; i < npcCount; i++) //hit
-		fp->read(fp, &gNpcTable[i].hit, 4, 1);
-	for (size_t i = 0; i < npcCount; i++) //view
-		fp->read(fp, &gNpcTable[i].view, 4, 1);
+	FILE *fp = fopen(path, "rb");
+	if (fp == NULL)
+		return false;
+
+	for (long n = 0; n < num; n++) //bits
+		gNpcTable[n].bits = File_ReadLE16(fp);
+	for (long n = 0; n < num; n++) //life
+		gNpcTable[n].life = File_ReadLE16(fp);
+	for (long n = 0; n < num; n++) //surf
+		fread(&gNpcTable[n].surf, 1, 1, fp);
+	for (long n = 0; n < num; n++) //destroy_voice
+		fread(&gNpcTable[n].destroy_voice, 1, 1, fp);
+	for (long n = 0; n < num; n++) //hit_voice
+		fread(&gNpcTable[n].hit_voice, 1, 1, fp);
+	for (long n = 0; n < num; n++) //size
+		fread(&gNpcTable[n].size, 1, 1, fp);
+	for (long n = 0; n < num; n++) //exp
+		gNpcTable[n].exp = File_ReadLE32(fp);
+	for (long n = 0; n < num; n++) //damage
+		gNpcTable[n].damage = File_ReadLE32(fp);
+	for (long n = 0; n < num; n++) //hit
+		fread(&gNpcTable[n].hit, 4, 1, fp);
+	for (long n = 0; n < num; n++) //view
+		fread(&gNpcTable[n].view, 4, 1, fp);
 		
-	SDL_RWclose(fp);	
+	fclose(fp);
 	return true;
 }
 
--- a/src/Profile.cpp
+++ b/src/Profile.cpp
@@ -1,6 +1,8 @@
+#include <stddef.h>
 #include <stdint.h>
+#include <stdio.h>
+#include <string.h>
 
-#include <SDL_rwops.h>
 #include "WindowsWrapper.h"
 
 #include "CommonDefines.h"
@@ -19,7 +21,7 @@
 #include "Stage.h"
 #include "Game.h"
 #include "BossLife.h"
-#include "SelStage.h"
+#include "File.h"
 
 const char *gDefaultName = "Profile.dat";
 const char *gProfileCode = "Do041220";
@@ -29,11 +31,11 @@
 	char path[PATH_LENGTH];
 	sprintf(path, "%s/%s", gModulePath, gDefaultName);
 	
-	SDL_RWops *fp = SDL_RWFromFile(path, "rb");
-	if (!fp)
+	FILE *fp = fopen(path, "rb");
+	if (fp == NULL)
 		return false;
 	
-	SDL_RWclose(fp);
+	fclose(fp);
 	return true;
 }
 
@@ -50,8 +52,8 @@
 	//Open file
 	PROFILE profile;
 	
-	SDL_RWops *fp = SDL_RWFromFile(path, "wb");
-	if (!fp)
+	FILE *fp = fopen(path, "wb");
+	if (fp == NULL)
 		return false;
 	
 	//Set up profile
@@ -78,41 +80,41 @@
 	memcpy(profile.flags, gFlagNPC, sizeof(profile.flags));
 	
 	//Write to file
-	SDL_RWwrite(fp, profile.code, 8, 1);
-	SDL_WriteLE32(fp, profile.stage);
-	SDL_WriteLE32(fp, profile.music);
-	SDL_WriteLE32(fp, profile.x);
-	SDL_WriteLE32(fp, profile.y);
-	SDL_WriteLE32(fp, profile.direct);
-	SDL_WriteLE16(fp, profile.max_life);
-	SDL_WriteLE16(fp, profile.star);
-	SDL_WriteLE16(fp, profile.life);
-	SDL_WriteLE16(fp, profile.a);
-	SDL_WriteLE32(fp, profile.select_arms);
-	SDL_WriteLE32(fp, profile.select_item);
-	SDL_WriteLE32(fp, profile.equip);
-	SDL_WriteLE32(fp, profile.unit);
-	SDL_WriteLE32(fp, profile.counter);
+	fwrite(profile.code, 8, 1, fp);
+	File_WriteLE32(profile.stage, fp);
+	File_WriteLE32(profile.music, fp);
+	File_WriteLE32(profile.x, fp);
+	File_WriteLE32(profile.y, fp);
+	File_WriteLE32(profile.direct, fp);
+	File_WriteLE16(profile.max_life, fp);
+	File_WriteLE16(profile.star, fp);
+	File_WriteLE16(profile.life, fp);
+	File_WriteLE16(profile.a, fp);
+	File_WriteLE32(profile.select_arms, fp);
+	File_WriteLE32(profile.select_item, fp);
+	File_WriteLE32(profile.equip, fp);
+	File_WriteLE32(profile.unit, fp);
+	File_WriteLE32(profile.counter, fp);
 	for (int arm = 0; arm < 8; arm++)
 	{
-		SDL_WriteLE32(fp, profile.arms[arm].code);
-		SDL_WriteLE32(fp, profile.arms[arm].level);
-		SDL_WriteLE32(fp, profile.arms[arm].exp);
-		SDL_WriteLE32(fp, profile.arms[arm].max_num);
-		SDL_WriteLE32(fp, profile.arms[arm].num);
+		File_WriteLE32(profile.arms[arm].code, fp);
+		File_WriteLE32(profile.arms[arm].level, fp);
+		File_WriteLE32(profile.arms[arm].exp, fp);
+		File_WriteLE32(profile.arms[arm].max_num, fp);
+		File_WriteLE32(profile.arms[arm].num, fp);
 	}
 	for (int item = 0; item < 32; item++)
-		SDL_WriteLE32(fp, profile.items[item].code);
+		File_WriteLE32(profile.items[item].code, fp);
 	for (int stage = 0; stage < 8; stage++)
 	{
-		SDL_WriteLE32(fp, profile.permitstage[stage].index);
-		SDL_WriteLE32(fp, profile.permitstage[stage].event);
+		File_WriteLE32(profile.permitstage[stage].index, fp);
+		File_WriteLE32(profile.permitstage[stage].event, fp);
 	}
-	SDL_RWwrite(fp, profile.permit_mapping, 0x80, 1);
-	SDL_RWwrite(fp, "FLAG", 4, 1);
-	SDL_RWwrite(fp, profile.flags, 1000, 1);
+	fwrite(profile.permit_mapping, 0x80, 1, fp);
+	fwrite("FLAG", 4, 1, fp);
+	fwrite(profile.flags, 1000, 1, fp);
 	
-	SDL_RWclose(fp);
+	fclose(fp);
 	return true;
 }
 
@@ -129,51 +131,51 @@
 	//Open file
 	PROFILE profile;
 	
-	SDL_RWops *fp = SDL_RWFromFile(path, "rb");
-	if (!fp)
+	FILE *fp = fopen(path, "rb");
+	if (fp == NULL)
 		return false;
 	
 	//Check header code
-	SDL_RWread(fp, profile.code, 8, 1);
+	fread(profile.code, 8, 1, fp);
 	if (memcmp(profile.code, gProfileCode, 8))
 		return false;
 	
 	//Read data
-	SDL_RWseek(fp, 0, RW_SEEK_SET); //Pixel epic redundant code 😎😎😎
-	SDL_RWread(fp, profile.code, 8, 1);
-	profile.stage = SDL_ReadLE32(fp);
-	profile.music = SDL_ReadLE32(fp);
-	profile.x = SDL_ReadLE32(fp);
-	profile.y = SDL_ReadLE32(fp);
-	profile.direct = SDL_ReadLE32(fp);
-	profile.max_life = SDL_ReadLE16(fp);
-	profile.star = SDL_ReadLE16(fp);
-	profile.life = SDL_ReadLE16(fp);
-	profile.a = SDL_ReadLE16(fp);
-	profile.select_arms = SDL_ReadLE32(fp);
-	profile.select_item = SDL_ReadLE32(fp);
-	profile.equip = SDL_ReadLE32(fp);
-	profile.unit = SDL_ReadLE32(fp);
-	profile.counter = SDL_ReadLE32(fp);
+	fseek(fp, 0, SEEK_SET); //Pixel epic redundant code 😎😎😎
+	fread(profile.code, 8, 1, fp);
+	profile.stage = File_ReadLE32(fp);
+	profile.music = File_ReadLE32(fp);
+	profile.x = File_ReadLE32(fp);
+	profile.y = File_ReadLE32(fp);
+	profile.direct = File_ReadLE32(fp);
+	profile.max_life = File_ReadLE16(fp);
+	profile.star = File_ReadLE16(fp);
+	profile.life = File_ReadLE16(fp);
+	profile.a = File_ReadLE16(fp);
+	profile.select_arms = File_ReadLE32(fp);
+	profile.select_item = File_ReadLE32(fp);
+	profile.equip = File_ReadLE32(fp);
+	profile.unit = File_ReadLE32(fp);
+	profile.counter = File_ReadLE32(fp);
 	for (int arm = 0; arm < 8; arm++)
 	{
-		profile.arms[arm].code = SDL_ReadLE32(fp);
-		profile.arms[arm].level = SDL_ReadLE32(fp);
-		profile.arms[arm].exp = SDL_ReadLE32(fp);
-		profile.arms[arm].max_num = SDL_ReadLE32(fp);
-		profile.arms[arm].num = SDL_ReadLE32(fp);
+		profile.arms[arm].code = File_ReadLE32(fp);
+		profile.arms[arm].level = File_ReadLE32(fp);
+		profile.arms[arm].exp = File_ReadLE32(fp);
+		profile.arms[arm].max_num = File_ReadLE32(fp);
+		profile.arms[arm].num = File_ReadLE32(fp);
 	}
 	for (int item = 0; item < 32; item++)
-		profile.items[item].code = SDL_ReadLE32(fp);
+		profile.items[item].code = File_ReadLE32(fp);
 	for (int stage = 0; stage < 8; stage++)
 	{
-		profile.permitstage[stage].index = SDL_ReadLE32(fp);
-		profile.permitstage[stage].event = SDL_ReadLE32(fp);
+		profile.permitstage[stage].index = File_ReadLE32(fp);
+		profile.permitstage[stage].event = File_ReadLE32(fp);
 	}
-	SDL_RWread(fp, profile.permit_mapping, 0x80, 1);
-	SDL_RWread(fp, profile.FLAG, 4, 1);
-	SDL_RWread(fp, profile.flags, 1000, 1);
-	SDL_RWclose(fp);
+	fread(profile.permit_mapping, 0x80, 1, fp);
+	fread(profile.FLAG, 4, 1, fp);
+	fread(profile.flags, 1000, 1, fp);
+	fclose(fp);
 	
 	//Set things
 	gSelectedArms = profile.select_arms;
--- a/src/TextScr.cpp
+++ b/src/TextScr.cpp
@@ -29,6 +29,7 @@
 #include "BossLife.h"
 #include "SelStage.h"
 #include "Flash.h"
+#include "Generic.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
 
@@ -105,16 +106,19 @@
 	char path[260];
 	sprintf(path, "%s/%s", gDataPath, name);
 
+	gTS.size = GetFileSizeLong(path);
+	if (gTS.size == -1)
+		return false;
+
 	//Open file
-	SDL_RWops *fp = SDL_RWFromFile(path, "rb");
-	if (!fp)
+	FILE *fp = fopen(path, "rb");
+	if (fp == NULL)
 		return false;
 
 	//Read data
-	gTS.size = SDL_RWsize(fp);
-	fp->read(fp, gTS.data, 1, gTS.size);
+	fread(gTS.data, 1, gTS.size, fp);
 	gTS.data[gTS.size] = 0;
-	fp->close(fp);
+	fclose(fp);
 
 	//Set path
 	strcpy(gTS.path, name);
@@ -131,30 +135,36 @@
 	char path[PATH_LENGTH];
 	sprintf(path, "%s/%s", gDataPath, "Head.tsc");
 
-	SDL_RWops *fp = SDL_RWFromFile(path, "rb");
-	if (!fp)
+	long head_size = GetFileSizeLong(path);
+	if (head_size == -1)
 		return false;
 
+	FILE *fp = fopen(path, "rb");
+	if (fp == NULL)
+		return false;
+
 	//Read Head.tsc
-	int head_size = SDL_RWsize(fp);
-	fp->read(fp, gTS.data, 1, head_size);
+	fread(gTS.data, 1, head_size, fp);
 	EncryptionBinaryData2((uint8_t*)gTS.data, head_size);
 	gTS.data[head_size] = 0;
-	SDL_RWclose(fp);
+	fclose(fp);
 
 	//Open stage's .tsc
 	sprintf(path, "%s/%s", gDataPath, name);
 
-	fp = SDL_RWFromFile(path, "rb");
-	if (!fp)
+	long body_size = GetFileSizeLong(path);
+	if (body_size == -1)
 		return false;
 
+	fp = fopen(path, "rb");
+	if (fp == NULL)
+		return false;
+
 	//Read stage's tsc
-	int body_size = SDL_RWsize(fp);
-	fp->read(fp, &gTS.data[head_size], 1, body_size);
+	fread(&gTS.data[head_size], 1, body_size, fp);
 	EncryptionBinaryData2((uint8_t*)&gTS.data[head_size], body_size);
 	gTS.data[head_size + body_size] = 0;
-	SDL_RWclose(fp);
+	fclose(fp);
 
 	//Set parameters
 	gTS.size = head_size + body_size;
--