shithub: cstory

Download patch

ref: c59f9ef4183c71c6375b24e783910b7e7fdd88d5
parent: 10d946aca25bc0db5f3d31544dc6b6a4d6085d0d
parent: 51a11eede1a5f17d6174fdf5e62f427f42a637ba
author: Cucky <[email protected]>
date: Tue Jan 29 11:41:11 EST 2019

Merge pull request #26 from Clownacy/master

Fix some errors and added Windows font loading and a bunch of NPCs

--- a/Makefile
+++ b/Makefile
@@ -20,8 +20,12 @@
 CXXFLAGS += -DFIX_BUGS
 endif
 
-ifeq ($(CONSOLE), 1)
-CXXFLAGS += -mconsole
+ifeq ($(WINDOWS), 1)
+	ifeq ($(CONSOLE), 1)
+	CXXFLAGS += -mconsole
+	endif
+CXXFLAGS += -DWINDOWS
+LIBS += -lkernel32
 endif
 
 CXXFLAGS += `sdl2-config --cflags` `pkg-config freetype2 --cflags`
@@ -61,7 +65,10 @@
 	NpcAct020 \
 	NpcAct040 \
 	NpcAct060 \
+	NpcAct080 \
 	NpcAct100 \
+	NpcAct120 \
+	NpcAct140 \
 	NpcAct200 \
 	NpcAct280 \
 	NpcAct300 \
--- a/res/bin2h.c
+++ b/res/bin2h.c
@@ -50,7 +50,7 @@
 
 			setvbuf(out_file, NULL, _IOFBF, 0x10000);
 
-			fprintf(out_file, "#pragma once\n\nconst unsigned char r%s[0x%X] = {\n\t", filename, in_file_size);
+			fprintf(out_file, "#pragma once\n\nconst unsigned char r%s[0x%lX] = {\n\t", filename, in_file_size);
 
 			for (long i = 0; i < in_file_size - 1; ++i)
 			{
--- a/src/Draw.cpp
+++ b/src/Draw.cpp
@@ -4,6 +4,18 @@
 #include <stdio.h>
 #include <stdint.h>
 
+#ifdef WINDOWS
+#define RECT WINRECT
+#define FindResource WinFindResource	// All these damn name collisions...
+#define DrawText WinDrawText
+#define LoadFont WinLoadFont
+#include <windows.h>
+#undef LoadFont
+#undef DrawText
+#undef FindResource
+#undef RECT
+#endif
+
 #include <SDL_render.h>
 #include <SDL_rwops.h>
 #include <SDL_timer.h>
@@ -375,8 +387,8 @@
 	
 	SDL_SetRenderTarget(gRenderer, surf[surf_no].texture);
 	
-	const unsigned char col_red = col & 0xFF0000 >> 16;
-	const unsigned char col_green = col & 0x00FF00 >> 8;
+	const unsigned char col_red = (col & 0xFF0000) >> 16;
+	const unsigned char col_green = (col & 0x00FF00) >> 8;
 	const unsigned char col_blue = col & 0x0000FF;
 	const unsigned char col_alpha = (col_red || col_green || col_blue) ? 0xFF : 0;
 
@@ -388,8 +400,55 @@
 	SDL_SetRenderTarget(gRenderer, NULL);
 }
 
-void InitTextObject()
+#ifdef WINDOWS
+static unsigned char* GetFontFromWindows(size_t *data_size, const char *font_name, unsigned int fontWidth, unsigned int fontHeight)
 {
+	unsigned char* buffer = NULL;
+
+#ifdef JAPANESE
+	const DWORD charset = SHIFTJIS_CHARSET;
+#else
+	const DWORD charset = DEFAULT_CHARSET;
+#endif
+
+	HFONT hfont = CreateFontA(fontHeight, fontWidth, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, charset, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FIXED_PITCH | FF_DONTCARE, font_name);
+
+	if (hfont == NULL)
+		hfont = CreateFontA(fontHeight, fontWidth, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, charset, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FIXED_PITCH | FF_DONTCARE, NULL);
+
+	if (hfont != NULL)
+	{
+		HDC hdc = CreateCompatibleDC(NULL);
+
+		if (hdc != NULL)
+		{
+			SelectObject(hdc, hfont);
+			const DWORD size = GetFontData(hdc, 0, 0, NULL, 0);
+
+			if (size != GDI_ERROR)
+			{
+				buffer = new unsigned char[size];
+
+				if (data_size != NULL)
+					*data_size = size;
+
+				if (GetFontData(hdc, 0, 0, buffer, size) != size)
+				{
+					delete[] buffer;
+					buffer = NULL;
+				}
+			}
+
+			DeleteDC(hdc);
+		}
+	}
+
+	return buffer;
+}
+#endif
+
+void InitTextObject(const char *font_name)
+{
 	//Get font size
 	unsigned int fontWidth, fontHeight;
 	if (gWindowScale == 1)
@@ -403,6 +462,24 @@
 		fontHeight = 10 * gWindowScale;
 	}
 	
+#ifdef WINDOWS
+	// Actually use the font Config.dat specifies
+	size_t data_size;
+	unsigned char *data = GetFontFromWindows(&data_size, font_name, fontWidth, fontHeight);
+
+	if (data != NULL)
+	{
+		gFont = LoadFontFromData(data, data_size, fontWidth, fontHeight);
+
+		delete[] data;
+
+		if (gFont)
+			return;
+	}
+#endif
+	// Fall back on the built-in fonts
+	(void)font_name;
+
 	//Open Font.ttf
 	char path[PATH_LENGTH];
 #ifdef JAPANESE
@@ -411,7 +488,7 @@
 	sprintf(path, "%s/cour.ttf", gDataPath);
 #endif
 
-	gFont = LoadFont(fontWidth, fontHeight, path);
+	gFont = LoadFont(path, fontWidth, fontHeight);
 }
 
 void PutText(int x, int y, const char *text, uint32_t color)
--- a/src/Draw.h
+++ b/src/Draw.h
@@ -66,7 +66,7 @@
 void Surface2Surface(int x, int y, RECT *rect, int to, int from);
 void CortBox(RECT *rect, uint32_t col);
 void CortBox2(RECT *rect, uint32_t col, int surf_no);
-void InitTextObject();
+void InitTextObject(const char *font_name);
 void PutText(int x, int y, const char *text, uint32_t color);
 void PutText2(int x, int y, const char *text, uint32_t color, int surf_no);
 void EndTextObject();
--- a/src/Font.cpp
+++ b/src/Font.cpp
@@ -2,7 +2,9 @@
 
 #include <stdbool.h>
 #include <stddef.h>
+#include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 
 #ifdef JAPANESE
 #include <iconv.h>
@@ -27,6 +29,7 @@
 {
 	FT_Library library;
 	FT_Face face;
+	unsigned char *data;
 #ifndef DISABLE_FONT_ANTIALIASING
 	bool lcd_mode;
 #endif
@@ -89,7 +92,7 @@
 	return charcode;
 }
 
-FontObject* LoadFont(unsigned int cell_width, unsigned int cell_height, char *font_filename)
+FontObject* LoadFontFromData(const unsigned char *data, size_t data_size, unsigned int cell_width, unsigned int cell_height)
 {
 	FontObject *font_object = (FontObject*)malloc(sizeof(FontObject));
 
@@ -99,10 +102,19 @@
 	font_object->lcd_mode = FT_Library_SetLcdFilter(font_object->library, FT_LCD_FILTER_DEFAULT) != FT_Err_Unimplemented_Feature;
 #endif
 
-	FT_New_Face(font_object->library, font_filename, 0, &font_object->face);
+	font_object->data = (unsigned char*)malloc(data_size);
+	memcpy(font_object->data, data, data_size);
 
-	unsigned int best_cell_width = 0;
-	unsigned int best_cell_height = 0;
+	FT_Error error = FT_New_Memory_Face(font_object->library, font_object->data, data_size, 0, &font_object->face);
+
+	if (error)
+	{
+		free(font_object->data);
+		FT_Done_FreeType(font_object->library);
+		free(font_object);
+		return NULL;
+	}
+
 	unsigned int best_pixel_width = 0;
 	unsigned int best_pixel_height = 0;
 
@@ -120,15 +132,10 @@
 		else
 		{
 			if (current_cell_width <= cell_width)
-			{
 				best_pixel_width = i;
-				best_cell_width = current_cell_width;
-			}
+
 			if (current_cell_height <= cell_height)
-			{
 				best_pixel_height = i;
-				best_cell_height = current_cell_height;
-			}
 		}
 	}
 
@@ -145,145 +152,176 @@
 	return font_object;
 }
 
+FontObject* LoadFont(const char *font_filename, unsigned int cell_width, unsigned int cell_height)
+{
+	FontObject *font_object = NULL;
+
+	FILE *file = fopen(font_filename, "rb");
+
+	if (file != NULL)
+	{
+		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);
+	}
+
+	return font_object;
+}
+
 void DrawText(FontObject *font_object, SDL_Renderer *renderer, SDL_Texture *texture, int x, int y, unsigned long colour, const char *string, size_t string_length)
 {
-	const unsigned char colours[3] = {(unsigned char)(colour >> 16), (unsigned char)(colour >> 8), (unsigned char)colour};
+	if (font_object != NULL)
+	{
+		const unsigned char colours[3] = {(unsigned char)(colour >> 16), (unsigned char)(colour >> 8), (unsigned char)colour};
 
-	SDL_Texture *old_render_target = SDL_GetRenderTarget(renderer);
-	SDL_SetRenderTarget(renderer, texture);
+		SDL_Texture *old_render_target = SDL_GetRenderTarget(renderer);
+		SDL_SetRenderTarget(renderer, texture);
 
-	int surface_width, surface_height;
-	SDL_GetRendererOutputSize(renderer, &surface_width, &surface_height);
+		int surface_width, surface_height;
+		SDL_GetRendererOutputSize(renderer, &surface_width, &surface_height);
 
-	SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormat(0, surface_width, surface_height, 0, SDL_PIXELFORMAT_RGBA32);
-	SDL_RenderReadPixels(renderer, NULL, SDL_PIXELFORMAT_RGBA32, surface->pixels, surface->pitch);
-	unsigned char (*surface_buffer)[surface->pitch / 4][4] = (unsigned char (*)[surface->pitch / 4][4])surface->pixels;
+		SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormat(0, surface_width, surface_height, 0, SDL_PIXELFORMAT_RGBA32);
+		SDL_RenderReadPixels(renderer, NULL, SDL_PIXELFORMAT_RGBA32, surface->pixels, surface->pitch);
+		unsigned char (*surface_buffer)[surface->pitch / 4][4] = (unsigned char (*)[surface->pitch / 4][4])surface->pixels;
 
-	FT_Face face = font_object->face;
+		FT_Face face = font_object->face;
 
-	unsigned int pen_x = 0;
+		unsigned int pen_x = 0;
 
-	const unsigned char *string_pointer = (unsigned char*)string;
-	const unsigned char *string_end = (unsigned char*)string + string_length;
+		const unsigned char *string_pointer = (unsigned char*)string;
+		const unsigned char *string_end = (unsigned char*)string + string_length;
 
-	while (string_pointer != string_end)
-	{
+		while (string_pointer != string_end)
+		{
 #ifdef JAPANESE
-		size_t out_size = 4;
-		unsigned char out_buffer[4];	// Max UTF-8 length is four bytes
-		unsigned char *out_pointer = out_buffer;
+			size_t out_size = 4;
+			unsigned char out_buffer[4];	// Max UTF-8 length is four bytes
+			unsigned char *out_pointer = out_buffer;
 
-		size_t in_size = ((*string_pointer >= 0x81 && *string_pointer <= 0x9F) || (*string_pointer >= 0xE0 && *string_pointer <= 0xEF)) ? 2 : 1;
-		unsigned char in_buffer[2];
-		unsigned char *in_pointer = in_buffer;
+			size_t in_size = ((*string_pointer >= 0x81 && *string_pointer <= 0x9F) || (*string_pointer >= 0xE0 && *string_pointer <= 0xEF)) ? 2 : 1;
+			unsigned char in_buffer[2];
+			unsigned char *in_pointer = in_buffer;
 
-		for (size_t i = 0; i < in_size; ++i)
-			in_buffer[i] = string_pointer[i];
+			for (size_t i = 0; i < in_size; ++i)
+				in_buffer[i] = string_pointer[i];
 
-		string_pointer += in_size;
-	
-		iconv(font_object->conv, (char**)&in_pointer, &in_size, (char**)&out_pointer, &out_size);
+			string_pointer += in_size;
 
-		const unsigned long val = UTF8ToCode(out_buffer, NULL);
+			iconv(font_object->conv, (char**)&in_pointer, &in_size, (char**)&out_pointer, &out_size);
+
+			const unsigned long val = UTF8ToCode(out_buffer, NULL);
 #else
-		unsigned int bytes_read;
-		const unsigned long val = UTF8ToCode(string_pointer, &bytes_read);
-		string_pointer += bytes_read;
+			unsigned int bytes_read;
+			const unsigned long val = UTF8ToCode(string_pointer, &bytes_read);
+			string_pointer += bytes_read;
 #endif
 
-		unsigned int glyph_index = FT_Get_Char_Index(face, val);
+			unsigned int glyph_index = FT_Get_Char_Index(face, val);
 
 #ifndef DISABLE_FONT_ANTIALIASING
-		FT_Load_Glyph(face, glyph_index, FT_LOAD_RENDER | (font_object->lcd_mode ? FT_LOAD_TARGET_LCD : 0));
+			FT_Load_Glyph(face, glyph_index, FT_LOAD_RENDER | (font_object->lcd_mode ? FT_LOAD_TARGET_LCD : 0));
 #else
-		FT_Load_Glyph(face, glyph_index, FT_LOAD_RENDER | FT_LOAD_MONOCHROME);
+			FT_Load_Glyph(face, glyph_index, FT_LOAD_RENDER | FT_LOAD_MONOCHROME);
 #endif
 
-		FT_Bitmap converted;
-		FT_Bitmap_New(&converted);
-		FT_Bitmap_Convert(font_object->library, &face->glyph->bitmap, &converted, 1);
+			FT_Bitmap converted;
+			FT_Bitmap_New(&converted);
+			FT_Bitmap_Convert(font_object->library, &face->glyph->bitmap, &converted, 1);
 
-		const int letter_x = x + pen_x + face->glyph->bitmap_left;
-		const int letter_y = y + ((FT_MulFix(face->ascender, face->size->metrics.y_scale) + (64 - 1)) / 64) - (face->glyph->metrics.horiBearingY / 64);
+			const int letter_x = x + pen_x + face->glyph->bitmap_left;
+			const int letter_y = y + ((FT_MulFix(face->ascender, face->size->metrics.y_scale) + (64 - 1)) / 64) - (face->glyph->metrics.horiBearingY / 64);
 
-		for (int iy = MAX(-letter_y, 0); letter_y + iy < MIN(letter_y + converted.rows, surface_height); ++iy)
-		{
-			if (face->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_LCD)
+			for (int iy = MAX(-letter_y, 0); letter_y + iy < MIN(letter_y + converted.rows, surface_height); ++iy)
 			{
-				for (int ix = MAX(-letter_x, 0); letter_x + ix < MIN(letter_x + (int)converted.width / 3, surface_width); ++ix)
+				if (face->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_LCD)
 				{
-					const unsigned char (*font_buffer)[converted.pitch / 3][3] = (unsigned char (*)[converted.pitch / 3][3])converted.buffer;
+					for (int ix = MAX(-letter_x, 0); letter_x + ix < MIN(letter_x + (int)converted.width / 3, surface_width); ++ix)
+					{
+						const unsigned char (*font_buffer)[converted.pitch / 3][3] = (unsigned char (*)[converted.pitch / 3][3])converted.buffer;
 
-					const unsigned char *font_pixel = font_buffer[iy][ix];
-					unsigned char *surface_pixel = surface_buffer[letter_y + iy][letter_x + ix];
+						const unsigned char *font_pixel = font_buffer[iy][ix];
+						unsigned char *surface_pixel = surface_buffer[letter_y + iy][letter_x + ix];
 
-					if (font_pixel[0] || font_pixel[1] || font_pixel[2])
-					{
-						for (unsigned int j = 0; j < 3; ++j)
+						if (font_pixel[0] || font_pixel[1] || font_pixel[2])
 						{
-							const double alpha = pow((font_pixel[j] / 255.0), 1.0 / 1.8);			// Gamma correction
-							surface_pixel[j] = (colours[j] * alpha) + (surface_pixel[j] * (1.0 - alpha));	// Alpha blending
-						}
+							for (unsigned int j = 0; j < 3; ++j)
+							{
+								const double alpha = pow((font_pixel[j] / 255.0), 1.0 / 1.8);			// Gamma correction
+								surface_pixel[j] = (colours[j] * alpha) + (surface_pixel[j] * (1.0 - alpha));	// Alpha blending
+							}
 
-						surface_pixel[3] = 0xFF;
+							surface_pixel[3] = 0xFF;
+						}
 					}
 				}
-			}
-			else if (face->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_GRAY)
-			{
-				for (int ix = MAX(-letter_x, 0); letter_x + ix < MIN(letter_x + (int)converted.width, surface_width); ++ix)
+				else if (face->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_GRAY)
 				{
-					unsigned char (*font_buffer)[converted.pitch] = (unsigned char (*)[converted.pitch])converted.buffer;
+					for (int ix = MAX(-letter_x, 0); letter_x + ix < MIN(letter_x + (int)converted.width, surface_width); ++ix)
+					{
+						unsigned char (*font_buffer)[converted.pitch] = (unsigned char (*)[converted.pitch])converted.buffer;
 
-					const double alpha = pow((double)font_buffer[iy][ix] / (converted.num_grays - 1), 1.0 / 1.8);			// Gamma-corrected
+						const double alpha = pow((double)font_buffer[iy][ix] / (converted.num_grays - 1), 1.0 / 1.8);			// Gamma-corrected
 
-					unsigned char *surface_pixel = surface_buffer[letter_y + iy][letter_x + ix];
+						unsigned char *surface_pixel = surface_buffer[letter_y + iy][letter_x + ix];
 
-					if (alpha)
-					{
-						for (unsigned int j = 0; j < 3; ++j)
-							surface_pixel[j] = (colours[j] * alpha) + (surface_pixel[j] * (1.0 - alpha));	// Alpha blending
+						if (alpha)
+						{
+							for (unsigned int j = 0; j < 3; ++j)
+								surface_pixel[j] = (colours[j] * alpha) + (surface_pixel[j] * (1.0 - alpha));	// Alpha blending
 
-						surface_pixel[3] = 0xFF;
+							surface_pixel[3] = 0xFF;
+						}
 					}
 				}
-			}
-			else if (face->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO)
-			{
-				for (int ix = MAX(-letter_x, 0); letter_x + ix < MIN(letter_x + (int)converted.width, surface_width); ++ix)
+				else if (face->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO)
 				{
-					unsigned char (*font_buffer)[converted.pitch] = (unsigned char (*)[converted.pitch])converted.buffer;
+					for (int ix = MAX(-letter_x, 0); letter_x + ix < MIN(letter_x + (int)converted.width, surface_width); ++ix)
+					{
+						unsigned char (*font_buffer)[converted.pitch] = (unsigned char (*)[converted.pitch])converted.buffer;
 
-					unsigned char *surface_pixel = surface_buffer[letter_y + iy][letter_x + ix];
+						unsigned char *surface_pixel = surface_buffer[letter_y + iy][letter_x + ix];
 
-					if (font_buffer[iy][ix])
-					{
-						for (unsigned int j = 0; j < 3; ++j)
-							surface_pixel[j] = colours[j];
+						if (font_buffer[iy][ix])
+						{
+							for (unsigned int j = 0; j < 3; ++j)
+								surface_pixel[j] = colours[j];
 
-						surface_pixel[3] = 0xFF;
+							surface_pixel[3] = 0xFF;
+						}
 					}
 				}
 			}
-		}
 
-		FT_Bitmap_Done(font_object->library, &converted);
+			FT_Bitmap_Done(font_object->library, &converted);
 
-		pen_x += face->glyph->advance.x / 64;
-	}
+			pen_x += face->glyph->advance.x / 64;
+		}
 
-	SDL_Texture *screen_texture = SDL_CreateTextureFromSurface(renderer, surface);
-	SDL_FreeSurface(surface);
-	SDL_RenderCopy(renderer, screen_texture, NULL, NULL);
-	SDL_DestroyTexture(screen_texture);
-	SDL_SetRenderTarget(renderer, old_render_target);
+		SDL_Texture *screen_texture = SDL_CreateTextureFromSurface(renderer, surface);
+		SDL_FreeSurface(surface);
+		SDL_RenderCopy(renderer, screen_texture, NULL, NULL);
+		SDL_DestroyTexture(screen_texture);
+		SDL_SetRenderTarget(renderer, old_render_target);
+	}
 }
 
 void UnloadFont(FontObject *font_object)
 {
+	if (font_object != NULL)
+	{
 #ifdef JAPANESE
-	iconv_close(font_object->conv);
+		iconv_close(font_object->conv);
 #endif
-	FT_Done_Face(font_object->face);
-	FT_Done_FreeType(font_object->library);
+		FT_Done_Face(font_object->face);
+		free(font_object->data);
+		FT_Done_FreeType(font_object->library);
+		free(font_object);
+	}
 }
--- a/src/Font.h
+++ b/src/Font.h
@@ -6,6 +6,7 @@
 
 typedef struct FontObject FontObject;
 
-FontObject* LoadFont(unsigned int cell_width, unsigned int cell_height, char *font_filename);
+FontObject* LoadFontFromData(const unsigned char *data, size_t data_size, unsigned int cell_width, unsigned int cell_height);
+FontObject* LoadFont(const char *font_filename, unsigned int cell_width, unsigned int cell_height);
 void DrawText(FontObject *font_object, SDL_Renderer *renderer, SDL_Texture *texture, int x, int y, unsigned long colour, const char *string, size_t string_length);
 void UnloadFont(FontObject *font_object);
--- a/src/Game.cpp
+++ b/src/Game.cpp
@@ -284,7 +284,7 @@
 	//Reset cliprect, flags, and give the player the nikumaru counter
 	grcGame.left = 0;
 	g_GameFlags = 0;
-	gMC.equip & 0x100;
+	gMC.equip |= 0x100;
 	
 	//Start loop
 	int wait = 0;
--- a/src/Main.cpp
+++ b/src/Main.cpp
@@ -284,7 +284,7 @@
 				}
 				
 				//Initialize stuff
-				InitTextObject();
+				InitTextObject(config.font_name);
 				InitTriangleTable();
 				
 				//Run game code
--- a/src/MiniMap.cpp
+++ b/src/MiniMap.cpp
@@ -21,15 +21,13 @@
 	for (int x = 0; x < gMap.width; x++)
 	{
 		uint8_t a = GetAttribute(x, line);
-		
-		printf("x: %d y: %d a: %d\n", x, line, a);
-		
+				
 		switch (a)
 		{
 			case 0:
 				Surface2Surface(x, line, &rcLevel[0], 9, 26);
 				break;
-				
+
 			case 68:
 			case 1:
 			case 64:
@@ -103,10 +101,10 @@
 		
 		PutFramePerSecound();
 		if (!Flip_SystemTask())
-		return 0;
+			return 0;
 	}
 	
-	RECT rcMiniMap = {0, gMap.width, 0, gMap.length};
+	RECT rcMiniMap = {0, 0, gMap.width, gMap.length};
 	rcView.right = --rcView.left + gMap.width + 2;
 	rcView.bottom = --rcView.top + gMap.length + 2;
 	CortBox2(&rcMiniMap, 0, 9);
@@ -147,30 +145,32 @@
 		if (!Flip_SystemTask())
 			return 0;
 	}
-	/*
-	for ( f = 8; f >= -1; --f )
+	
+	for (int f = 8; f >= -1; --f)
 	{
-	GetTrg();
-	if ( gKey & 0x8000 )
-	{
-	v3 = Call_Escape(gscreen);
-	if ( !v3 )
-	return 0;
-	if ( v3 == 2 )
-	return 2;
+		GetTrg();
+
+		if (gKey & KEY_ESCAPE)
+		{
+			int escRet = Call_Escape();
+			if (escRet == 0)
+				return 0;
+			if (escRet == 2)
+				return 2;
+		}
+
+		PutBitmap4(&grcGame, 0, 0, &grcGame, 10);
+		rcView.left = 160 - f * gMap.width / 16;
+		rcView.right = f * gMap.width / 16 + 160;
+		rcView.top = 120 - f * gMap.length / 16;
+		rcView.bottom = f * gMap.length / 16 + 120;
+		PutMapName(true);
+		CortBox(&rcView, 0);
+
+		PutFramePerSecound();
+		if (!Flip_SystemTask())
+			return 0;
 	}
-	PutBitmap4(&grcGame, 0, 0, &grcGame, 10);
-	rcView.left = 160 - f * gMap.width / 16;
-	rcView.right = f * gMap.width / 16 + 160;
-	rcView.top = 120 - f * gMap.length / 16;
-	rcView.bottom = f * gMap.length / 16 + 120;
-	PutMapName(1);
-	CortBox(&rcView, 0);
-	PutFramePerSecound();
-	if ( !Flip_SystemTask(gscreen) )
-	return 0;
-	}
-	*/
-	
+
 	return 1;
 }
\ No newline at end of file
--- a/src/NpChar.cpp
+++ b/src/NpChar.cpp
@@ -16,6 +16,9 @@
 
 NPCHAR gNPC[NPC_MAX];
 
+int gSuperXpos;
+int gSuperYpos;
+
 const char *gPassPixEve = "PXE\0";
 
 void InitNpChar()
--- a/src/NpChar.h
+++ b/src/NpChar.h
@@ -73,6 +73,9 @@
 
 extern NPCHAR gNPC[NPC_MAX];
 
+extern int gSuperXpos;
+extern int gSuperYpos;
+
 void InitNpChar();
 bool LoadEvent(char *path_event);
 void SetNpChar(int code_char, int x, int y, int xm, int ym, int dir, NPCHAR *npc, int start_index);
--- a/src/NpcAct.h
+++ b/src/NpcAct.h
@@ -9,6 +9,8 @@
 void ActNpc004(NPCHAR *npc);
 void ActNpc005(NPCHAR *npc);
 void ActNpc006(NPCHAR *npc);
+void ActNpc007(NPCHAR *npc);
+void ActNpc008(NPCHAR *npc);
 
 void ActNpc015(NPCHAR *npc);
 void ActNpc016(NPCHAR *npc);
@@ -20,26 +22,56 @@
 void ActNpc022(NPCHAR *npc);
 void ActNpc023(NPCHAR *npc);
 
+void ActNpc025(NPCHAR *npc);
+
+void ActNpc029(NPCHAR *npc);
 void ActNpc030(NPCHAR *npc);
 
 void ActNpc032(NPCHAR *npc);
 
+void ActNpc034(NPCHAR *npc);
+
 void ActNpc037(NPCHAR *npc);
 
 void ActNpc039(NPCHAR *npc);
 
+void ActNpc042(NPCHAR *npc);
+void ActNpc043(NPCHAR *npc);
+
+void ActNpc046(NPCHAR *npc);
+
+void ActNpc058(NPCHAR *npc);
 void ActNpc059(NPCHAR *npc);
 
 void ActNpc062(NPCHAR *npc);
 
-void ActNpc032(NPCHAR *npc);
-
 void ActNpc064(NPCHAR *npc);
 void ActNpc065(NPCHAR *npc);
 
+void ActNpc070(NPCHAR *npc);
+void ActNpc071(NPCHAR *npc);
+void ActNpc072(NPCHAR *npc);
 void ActNpc073(NPCHAR *npc);
+void ActNpc074(NPCHAR *npc);
+void ActNpc075(NPCHAR *npc);
+void ActNpc076(NPCHAR *npc);
+void ActNpc077(NPCHAR *npc);
+void ActNpc078(NPCHAR *npc);
+void ActNpc079(NPCHAR *npc);
 
+void ActNpc083(NPCHAR *npc);
+void ActNpc084(NPCHAR *npc);
+void ActNpc085(NPCHAR *npc);
+void ActNpc086(NPCHAR *npc);
+void ActNpc087(NPCHAR *npc);
+
+void ActNpc116(NPCHAR *npc);
+
 void ActNpc119(NPCHAR *npc);
+
+void ActNpc125(NPCHAR *npc);
+
+void ActNpc151(NPCHAR *npc);
 
 void ActNpc211(NPCHAR *npc);
 
--- a/src/NpcAct000.cpp
+++ b/src/NpcAct000.cpp
@@ -620,6 +620,188 @@
 		npc->rect = rcLeft[npc->ani_no];
 }
 
+//Basil
+void ActNpc007(NPCHAR *npc)
+{
+	RECT rcLeft[3];
+	RECT rcRight[3];
+
+	rcLeft[0] = {256, 64, 288, 80};
+	rcLeft[1] = {256, 80, 288, 96};
+	rcLeft[2] = {256, 96, 288, 112};
+
+	rcRight[0] = {288, 64, 320, 80};
+	rcRight[1] = {288, 80, 320, 96};
+	rcRight[2] = {288, 96, 320, 112};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->x = gMC.x;
+
+			if (npc->direct == 0)
+				npc->act_no = 1;
+			else
+				npc->act_no = 2;
+
+			break;
+
+		case 1:
+			npc->xm -= 0x40;
+
+			if (npc->x < gMC.x - 0x18000)
+				npc->act_no = 2;
+
+			if (npc->flag & 1)
+			{
+				npc->xm = 0;
+				npc->act_no = 2;
+			}
+
+			break;
+
+		case 2:
+			npc->xm += 0x40;
+
+			if (npc->x > gMC.x + 0x18000)
+				npc->act_no = 1;
+
+			if (npc->flag & 4)
+			{
+				npc->xm = 0;
+				npc->act_no = 1;
+			}
+
+			break;
+	}
+
+	if (npc->xm >= 0)
+		npc->direct = 2;
+	else
+		npc->direct = 0;
+
+	if (npc->xm > 0x5FF)
+		npc->xm = 0x5FF;
+	if (npc->xm < -0x5FF)
+		npc->xm = -0x5FF;
+
+	npc->x += npc->xm;
+
+	if (++npc->ani_wait > 1)
+	{
+		npc->ani_wait = 0;
+		++npc->ani_no;
+	}
+
+	if (npc->ani_no > 2)
+		npc->ani_no = 0;
+
+	if (npc->direct == 0)
+		npc->rect = rcLeft[npc->ani_no];
+	else
+		npc->rect = rcRight[npc->ani_no];
+}
+
+//Beetle (Follows you, Egg Corridor)
+void ActNpc008(NPCHAR *npc)
+{
+	RECT rcLeft[2];
+	RECT rcRight[2];
+
+	rcLeft[0] = {80, 80, 96, 96};
+	rcLeft[1] = {96, 80, 112, 96};
+
+	rcRight[0] = {80, 96, 96, 112};
+	rcRight[1] = {96, 96, 112, 112};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			if (gMC.x >= npc->x + 0x2000 || gMC.x <= npc->x - 0x2000)
+			{
+				npc->bits &= ~0x20;
+				npc->rect.right = 0;
+				npc->damage = 0;
+				npc->xm = 0;
+				npc->ym = 0;
+				return;
+			}
+
+			npc->bits |= 0x20;
+			npc->ym = -0x100;
+			npc->tgt_y = npc->y;
+			npc->act_no = 1;
+			npc->damage = 2;
+
+			if (npc->direct == 0)
+			{
+				npc->x = gMC.x + 0x20000;
+				npc->xm = -0x2FF;
+			}
+			else
+			{
+				npc->x = gMC.x - 0x20000;
+				npc->xm = 0x2FF;
+			}
+
+			break;
+
+		case 1:
+			if (npc->x <= gMC.x)
+			{
+				npc->direct = 2;
+				npc->xm += 0x10;
+			}
+			else
+			{
+				npc->direct = 0;
+				npc->xm -= 0x10;
+			}
+
+			if (npc->xm > 0x2FF)
+				npc->xm = 0x2FF;
+			if (npc->xm < -0x2FF)
+				npc->xm = -0x2FF;
+
+			if (npc->y >= npc->tgt_y)
+				npc->ym -= 8;
+			else
+				npc->ym += 8;
+
+			if (npc->ym > 0x100)
+				npc->ym = 0x100;
+			if (npc->ym < -0x100)
+				npc->ym = -0x100;
+
+			if (npc->shock)
+			{
+				npc->x += npc->xm / 2;
+				npc->y += npc->ym / 2;
+			}
+			else
+			{
+				npc->x += npc->xm;
+				npc->y += npc->ym;
+			}
+
+			break;
+	}
+
+	if (++npc->ani_wait > 1)
+	{
+		npc->ani_wait = 0;
+		++npc->ani_no;
+	}
+
+	if (npc->ani_no > 1)
+		npc->ani_no = 0;
+
+	if (npc->direct == 0)
+		npc->rect = rcLeft[npc->ani_no];
+	else
+		npc->rect = rcRight[npc->ani_no];
+}
+
 //Chest (closed)
 void ActNpc015(NPCHAR *npc)
 {
--- a/src/NpcAct020.cpp
+++ b/src/NpcAct020.cpp
@@ -108,6 +108,166 @@
 	npc->rect = rect[npc->ani_no];
 }
 
+// Egg Corridor lift
+void ActNpc025(NPCHAR *npc)
+{
+	RECT rcLeft[2];
+
+	rcLeft[0] = {256, 64, 288, 80};
+	rcLeft[1] = {256, 80, 288, 96};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->ani_no = 0;
+			npc->ani_wait = 0;
+			npc->x += 0x1000;
+			// Fallthrough
+		case 1:
+			if (++npc->act_wait > 150)
+			{
+				npc->act_wait = 0;
+				++npc->act_no;
+			}
+
+			break;
+
+		case 2:
+			if (++npc->act_wait > 0x40)
+			{
+				npc->act_wait = 0;
+				++npc->act_no;
+			}
+			else
+			{
+				npc->y -= 0x200;
+			}
+
+			break;
+
+		case 3:
+			if (++npc->act_wait > 150)
+			{
+				npc->act_wait = 0;
+				++npc->act_no;
+			}
+
+			break;
+
+		case 4:
+			if (++npc->act_wait > 0x40)
+			{
+				npc->act_wait = 0;
+				++npc->act_no;
+			}
+			else
+			{
+				npc->y -= 0x200;
+			}
+
+			break;
+
+		case 5:
+			if (++npc->act_wait > 150)
+			{
+				npc->act_wait = 0;
+				++npc->act_no;
+			}
+
+			break;
+
+		case 6:
+			if (++npc->act_wait > 0x40)
+			{
+				npc->act_wait = 0;
+				++npc->act_no;
+			}
+			else
+			{
+				npc->y += 0x200;
+			}
+
+			break;
+
+		case 7:
+			if (++npc->act_wait > 150)
+			{
+				npc->act_wait = 0;
+				++npc->act_no;
+			}
+
+			break;
+
+		case 8:
+			if (++npc->act_wait > 0x40)
+			{
+				npc->act_wait = 0;
+				npc->act_no = 1;
+			}
+			else
+			{
+				npc->y += 0x200;
+			}
+
+			break;
+	}
+
+	switch ( npc->act_no )
+	{
+		case 2:
+		case 4:
+		case 6:
+		case 8:
+			if (++npc->ani_wait > 1)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 1)
+				npc->ani_no = 0;
+
+			break;
+	}
+
+	npc->rect = rcLeft[npc->ani_no];
+}
+
+//Cthulhu
+void ActNpc029(NPCHAR *npc)
+{
+	RECT rcLeft[2];
+	RECT rcRight[2];
+
+	rcLeft[0] = {0, 192, 16, 216};
+	rcLeft[1] = {16, 192, 32, 216};
+
+	rcRight[0] = {0, 216, 16, 240};
+	rcRight[1] = {16, 216, 32, 240};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->ani_no = 0;
+			npc->ani_wait = 0;
+			// Fallthrough
+		case 1:
+			if (npc->x - 0x6000 < gMC.x && npc->x + 0x6000 > gMC.x && npc->y - 0x6000 < gMC.y && npc->y + 0x2000 > gMC.y)
+				npc->ani_no = 1;
+			else
+				npc->ani_no = 0;
+
+			break;
+	}
+
+	if (npc->direct == 0)
+		npc->rect = rcLeft[npc->ani_no];
+	else
+		npc->rect = rcRight[npc->ani_no];
+}
+
 //Gunsmith
 void ActNpc030(NPCHAR *npc)
 {
@@ -186,6 +346,21 @@
 		npc->ani_no = 0;
 
 	npc->rect = rect[npc->ani_no];
+}
+
+// Bed
+void ActNpc034(NPCHAR *npc)
+{
+	RECT rcLeft[1];
+	RECT rcRight[1];
+
+	rcLeft[0] = {192, 48, 224, 64};
+	rcRight[0] = {192, 184, 224, 200};
+
+	if (npc->direct == 0)
+		npc->rect = rcLeft[0];
+	else
+		npc->rect = rcRight[0];
 }
 
 //Signpost
--- a/src/NpcAct040.cpp
+++ b/src/NpcAct040.cpp
@@ -9,6 +9,502 @@
 #include "Back.h"
 #include "Triangle.h"
 
+// Sue
+void ActNpc042(NPCHAR *npc)
+{
+	RECT rcLeft[13];
+	RECT rcRight[13];
+
+	rcLeft[0] = {0, 0, 16, 16};
+	rcLeft[1] = {16, 0, 32, 16};
+	rcLeft[2] = {32, 0, 48, 16};
+	rcLeft[3] = {0, 0, 16, 16};
+	rcLeft[4] = {48, 0, 64, 16};
+	rcLeft[5] = {0, 0, 16, 16};
+	rcLeft[6] = {64, 0, 80, 16};
+	rcLeft[7] = {80, 32, 96, 48};
+	rcLeft[8] = {96, 32, 112, 48};
+	rcLeft[9] = {128, 32, 144, 48};
+	rcLeft[10] = {0, 0, 16, 16};
+	rcLeft[11] = {112, 32, 128, 48};
+	rcLeft[12] = {160, 32, 176, 48};
+
+	rcRight[0] = {0, 16, 16, 32};
+	rcRight[1] = {16, 16, 32, 32};
+	rcRight[2] = {32, 16, 48, 32};
+	rcRight[3] = {0, 16, 16, 32};
+	rcRight[4] = {48, 16, 64, 32};
+	rcRight[5] = {0, 16, 16, 32};
+	rcRight[6] = {64, 16, 80, 32};
+	rcRight[7] = {80, 48, 96, 64};
+	rcRight[8] = {96, 48, 112, 64};
+	rcRight[9] = {128, 48, 144, 64};
+	rcRight[10] = {0, 16, 16, 32};
+	rcRight[11] = {112, 48, 128, 64};
+	rcRight[12] = {160, 48, 176, 64};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->ani_no = 0;
+			npc->ani_wait = 0;
+			npc->xm = 0;
+			// Fallthrough
+		case 1:
+			if (Random(0, 120) == 10)
+			{
+				npc->act_no = 2;
+				npc->act_wait = 0;
+				npc->ani_no = 1;
+			}
+
+			break;
+
+		case 2:
+			if (++npc->act_wait > 8)
+			{
+				npc->act_no = 1;
+				npc->ani_no = 0;
+			}
+
+			break;
+
+		case 3:
+			npc->act_no = 4;
+			npc->ani_no = 2;
+			npc->ani_wait = 0;
+			// Fallthrough
+		case 4:
+			if (++npc->ani_wait > 4)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 5)
+				npc->ani_no = 2;
+
+			if (npc->direct == 0)
+				npc->xm = -0x200;
+			else
+				npc->xm = 0x200;
+
+			break;
+
+		case 5:
+			npc->ani_no = 6;
+			npc->xm = 0;
+			break;
+
+		case 6:
+			PlaySoundObject(50, 1);
+			npc->act_wait = 0;
+			npc->act_no = 7;
+			npc->ani_no = 7;
+			// Fallthrough
+		case 7:
+			if (++npc->act_wait > 10)
+				npc->act_no = 0;
+
+			break;
+
+		case 8:
+			PlaySoundObject(50, 1);
+			npc->act_wait = 0;
+			npc->act_no = 9;
+			npc->ani_no = 7;
+			npc->ym = -0x200;
+
+			if (npc->direct == 0)
+				npc->xm = 0x400;
+			else
+				npc->xm = -0x400;
+
+			// Fallthrough
+		case 9:
+			if (++npc->act_wait > 3 && npc->flag & 8)
+			{
+				npc->act_no = 10;
+
+				if (npc->direct == 0)
+					npc->direct = 2;
+				else
+					npc->direct = 0;
+			}
+
+			break;
+
+		case 10:
+			npc->xm = 0;
+			npc->ani_no = 8;
+			break;
+
+		case 11:
+			npc->act_no = 12;
+			npc->act_wait = 0;
+			npc->ani_no = 9;
+			npc->ani_wait = 0;
+			npc->xm = 0;
+			// Fallthrough
+		case 12:
+			if (++npc->ani_wait > 8)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 10)
+				npc->ani_no = 9;
+
+			break;
+
+		case 13:
+			npc->ani_no = 11;
+			npc->xm = 0;
+			npc->ym = 0;
+			npc->act_no = 14;
+
+			int i;
+			for (i = 0; i < 0x200 && gNPC[i].code_event != 501; ++i);
+
+			if (i == 0x200)
+			{
+				npc->act_no = 0;
+				break;
+			}
+			else
+			{
+				npc->pNpc = &gNPC[i];
+			}
+			// Fallthrough
+		case 14:
+			if (npc->pNpc->direct == 0)
+				npc->direct = 2;
+			else
+				npc->direct = 0;
+
+			if (npc->pNpc->direct == 0)
+				npc->x = npc->pNpc->x - 0xC00;
+			else
+				npc->x = npc->pNpc->x + 0xC00;
+
+			npc->y = npc->pNpc->y + 0x800;
+
+			if (npc->pNpc->ani_no == 2 || npc->pNpc->ani_no == 4)
+				npc->y -= 0x200;
+
+			break;
+
+		case 15:
+			npc->act_no = 16;
+			SetNpChar(257, npc->x + 0x10000, npc->y, 0, 0, 0, 0, 0);
+			SetNpChar(257, npc->x + 0x10000, npc->y, 0, 0, 2, 0, 0x80);
+			npc->xm = 0;
+			npc->ani_no = 0;
+			// Fallthrough
+		case 16:
+			gSuperXpos = npc->x - 0x3000;
+			gSuperYpos = npc->y - 0x1000;
+			break;
+
+		case 17:
+			npc->xm = 0;
+			npc->ani_no = 12;
+			gSuperXpos = npc->x;
+			gSuperYpos = npc->y - 0x1000;
+			break;
+
+		case 20:
+			npc->act_no = 21;
+			npc->ani_no = 2;
+			npc->ani_wait = 0;
+			// Fallthrough
+		case 21:
+			if (++npc->ani_wait > 2)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 5)
+				npc->ani_no = 2;
+
+			if (npc->direct == 0)
+				npc->xm = -0x400;
+			else
+				npc->xm = 0x400;
+
+			if (npc->x < gMC.x - 0x1000)
+			{
+				npc->direct = 2;
+				npc->act_no = 0;
+			}
+
+			break;
+
+		case 30:
+			npc->act_no = 31;
+			npc->ani_no = 2;
+			npc->ani_wait = 0;
+			// Fallthrough
+		case 31:
+			if (++npc->ani_wait > 2)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 5)
+				npc->ani_no = 2;
+
+			if (npc->direct == 0)
+				npc->xm = -0x400;
+			else
+				npc->xm = 0x400;
+
+			break;
+
+		case 40:
+			npc->act_no = 41;
+			npc->ani_no = 9;
+			npc->ym = -0x400;
+			break;
+	}
+
+	if (npc->act_no != 14)
+	{
+		npc->ym += 0x40;
+
+		if (npc->xm > 0x400)
+			npc->xm = 0x400;
+		if (npc->xm < -0x400)
+			npc->xm = -0x400;
+
+		if (npc->ym > 0x5FF)
+			npc->ym = 0x5FF;
+
+		npc->x += npc->xm;
+		npc->y += npc->ym;
+	}
+
+	if (npc->direct == 0)
+		npc->rect = rcLeft[npc->ani_no];
+	else
+		npc->rect = rcRight[npc->ani_no];
+}
+
+//Chalkboard
+void ActNpc043(NPCHAR *npc)
+{
+	RECT rcLeft[1];
+	RECT rcRight[1];
+
+	rcLeft[0] = {128, 80, 168, 112};
+	rcRight[0] = {168, 80, 208, 112};
+
+	if (npc->act_no == 0)
+	{
+		npc->act_no = 1;
+		npc->y -= 0x2000;
+	}
+
+	if (npc->direct == 0)
+		npc->rect = rcLeft[0];
+	else
+		npc->rect = rcRight[0];
+}
+
+//H/V Trigger
+void ActNpc046(NPCHAR *npc)
+{
+	RECT rect[1];
+	rect[0] = {0, 0, 16, 16};
+
+	npc->bits |= 0x100;
+
+	if (npc->direct == 0)
+	{
+		if (npc->x >= gMC.x)
+			npc->x -= 0x5FF;
+		else
+			npc->x += 0x5FF;
+	}
+	else
+	{
+		if (npc->y >= gMC.y)
+			npc->y -= 0x5FF;
+		else
+			npc->y += 0x5FF;
+	}
+
+	npc->rect = rect[0];
+}
+
+//Basu (Egg Corridor)
+void ActNpc058(NPCHAR *npc)
+{
+	unsigned __int8 v1; // ST2F_1@42
+	char v2; // ST2F_1@42
+	int a5; // ST24_4@42
+	int a4; // ST28_4@42
+	RECT *v5; // edx@54
+	RECT *v6; // eax@54
+	RECT *v7; // edx@55
+	RECT *v8; // eax@55
+	int routine; // [sp+0h] [bp-70h]@1
+
+	RECT rcLeft[3];
+	RECT rcRight[3];
+
+	rcLeft[0] = {192, 0, 216, 24};
+	rcLeft[1] = {216, 0, 240, 24};
+	rcLeft[2] = {240, 0, 264, 24};
+
+	rcRight[0] = {192, 24, 216, 48};
+	rcRight[1] = {216, 24, 240, 48};
+	rcRight[2] = {240, 24, 264, 48};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			if ( gMC.x >= npc->x + 0x2000 || gMC.x <= npc->x - 0x2000 )
+			{
+				npc->rect.right = 0;
+				npc->damage = 0;
+				npc->xm = 0;
+				npc->ym = 0;
+				npc->bits &= ~0x20;
+			}
+			else
+			{
+				npc->bits |= 0x20;
+				npc->ym = -0x100;
+				npc->tgt_x = npc->x;
+				npc->tgt_y = npc->y;
+				npc->act_no = 1;
+				npc->act_wait = 0;
+				npc->count1 = npc->direct;
+				npc->count2 = 0;
+				npc->damage = 6;
+
+				if (npc->direct == 0)
+				{
+					npc->x = gMC.x + 0x20000;
+					npc->xm = -0x2FFu;
+				}
+				else
+				{
+					npc->x = gMC.x - 0x20000;
+					npc->xm = 0x2FF;
+				}
+			}
+
+			break;
+
+		case 1:
+			if (npc->x <= gMC.x)
+			{
+				npc->direct = 2;
+				npc->xm += 0x10;
+			}
+			else
+			{
+				npc->direct = 0;
+				npc->xm -= 0x10;
+			}
+
+			if (npc->flag & 1)
+				npc->xm = 0x200;
+
+			if (npc->flag & 4)
+				npc->xm = -0x200;
+
+			if (npc->y >= npc->tgt_y)
+				npc->ym -= 8;
+			else
+				npc->ym += 8;
+
+			if (npc->xm > 0x2FF)
+				npc->xm = 0x2FF;
+			if (npc->xm < -0x2FF)
+				npc->xm = -0x2FF;
+
+			if (npc->ym > 0x100)
+				npc->ym = 0x100;
+			if (npc->ym < -0x100)
+				npc->ym = -0x100;
+
+			if (npc->shock)
+			{
+				npc->x += npc->xm / 2;
+				npc->y += npc->ym / 2;
+			}
+			else
+			{
+				npc->x += npc->xm;
+				npc->y += npc->ym;
+			}
+
+			if (gMC.x > npc->x + 0x32000 || gMC.x < npc->x - 0x32000)	// TODO: Maybe do something about this for widescreen
+			{
+				npc->act_no = 0;
+				npc->xm = 0;
+				npc->direct = npc->count1;
+				npc->x = npc->tgt_x;
+				npc->rect.right = 0;
+				npc->damage = 0;
+				break;
+			}
+
+			// Fallthrough
+		case 2:
+			if (npc->act_no)
+			{
+				if (npc->act_wait < 150)
+					++npc->act_wait;
+
+				if (npc->act_wait == 150)
+				{
+					if ((++npc->count2 % 8) == 0 && npc->x < gMC.x + 0x14000 && npc->x > gMC.x - 0x14000)	// TODO: Maybe do something about this for tallscreen
+					{
+						unsigned char deg = GetArktan(npc->x - gMC.x, npc->y - gMC.y);
+						unsigned char rand_deg = Random(-6, 6) + deg;
+						int ym = 2 * GetSin(rand_deg);
+						int xm = 2 * GetCos(rand_deg);
+						SetNpChar(84, npc->x, npc->y, xm, ym, 0, 0, 0x100);
+						PlaySoundObject(39, 1);
+					}
+
+					if (npc->count2 > 8)
+					{
+						npc->act_wait = 0;
+						npc->count2 = 0;
+					}
+				}
+			}
+
+			if (++npc->ani_wait > 1)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 1)
+				npc->ani_no = 0;
+
+			if (npc->act_wait > 120 && npc->act_wait / 2 % 2 == 1 && npc->ani_no == 1)
+				npc->ani_no = 2;
+
+			if (npc->direct == 0)
+				npc->rect = rcLeft[npc->ani_no];
+			else
+				npc->rect = rcRight[npc->ani_no];
+
+			break;
+	}
+}
+
 //Eye door
 void ActNpc059(NPCHAR *npc)
 {
--- a/src/NpcAct060.cpp
+++ b/src/NpcAct060.cpp
@@ -9,6 +9,7 @@
 #include "Back.h"
 #include "Triangle.h"
 #include "Map.h"
+#include "CommonDefines.h"
 
 //Kazuma at computer
 void ActNpc062(NPCHAR *npc)
@@ -257,6 +258,137 @@
 		npc->rect = rect_right[npc->ani_no];
 }
 
+//Sparkle
+void ActNpc070(NPCHAR *npc)
+{
+	RECT rect[4];
+
+	rect[0] = {96, 48, 112, 64};
+	rect[1] = {112, 48, 128, 64};
+	rect[2] = {128, 48, 144, 64};
+	rect[3] = {144, 48, 160, 64};
+
+	if (++npc->ani_wait > 3)
+	{
+		npc->ani_wait = 0;
+		++npc->ani_no;
+	}
+
+	if (npc->ani_no > 3)
+		npc->ani_no = 0;
+
+	npc->rect = rect[npc->ani_no];
+}
+
+//Chinfish
+void ActNpc071(NPCHAR *npc)
+{
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->tgt_x = npc->x;
+			npc->tgt_y = npc->y;
+			npc->ym = 0x80;
+			// Fallthrough
+		case 1:
+			if (npc->tgt_y < npc->y)
+				npc->ym -= 8;
+			if (npc->tgt_y > npc->y)
+				npc->ym += 8;
+
+			if (npc->ym > 0x100)
+				npc->ym = 0x100;
+			if (npc->ym < -0x100)
+				npc->ym = -0x100;
+
+			break;
+	}
+
+	npc->x += npc->xm;
+	npc->y += npc->ym;
+
+	RECT rcLeft[3];
+	RECT rcRight[3];
+
+	rcLeft[0].left = 64;
+	rcLeft[0].top = 32;
+	rcLeft[0].right = 80;
+	rcLeft[0].bottom = 48;
+	rcLeft[1].left = 80;
+	rcLeft[1].top = 32;
+	rcLeft[1].right = 96;
+	rcLeft[1].bottom = 48;
+	rcLeft[2].left = 96;
+	rcLeft[2].top = 32;
+	rcLeft[2].right = 112;
+	rcLeft[2].bottom = 48;
+
+	rcRight[0].left = 64;
+	rcRight[0].top = 48;
+	rcRight[0].right = 80;
+	rcRight[0].bottom = 64;
+	rcRight[1].left = 80;
+	rcRight[1].top = 48;
+	rcRight[1].right = 96;
+	rcRight[1].bottom = 64;
+	rcRight[2].left = 96;
+	rcRight[2].top = 48;
+	rcRight[2].right = 112;
+	rcRight[2].bottom = 64;
+
+	if (++npc->ani_wait > 4)
+	{
+		npc->ani_wait = 0;
+		++npc->ani_no;
+	}
+
+	if (npc->ani_no > 1)
+		npc->ani_no = 0;
+
+	if (npc->shock)
+		npc->ani_no = 2;
+
+	if (npc->direct == 0)
+		npc->rect = rcLeft[npc->ani_no];
+	else
+		npc->rect = rcRight[npc->ani_no];
+}
+
+//Sprinkler
+void ActNpc072(NPCHAR *npc)
+{
+	if (npc->direct == 0)
+	{
+		if (++npc->ani_wait > 1)
+		{
+			npc->ani_wait = 0;
+			++npc->ani_no;
+		}
+
+		if (npc->ani_no > 1)
+		{
+			npc->ani_no = 0;
+			return;
+		}
+
+		if (gMC.x < npc->x + (WINDOW_WIDTH * 0x200) && gMC.x > npc->x - (WINDOW_WIDTH * 0x200) && gMC.y < npc->y + (WINDOW_HEIGHT * 0x200) && gMC.y > npc->y - (WINDOW_HEIGHT * 0x200))
+		{
+			if (++npc->act_no % 2)
+				SetNpChar(73, npc->x, npc->y, 2 * Random(-0x200, 0x200), 3 * Random(-0x200, 0x80), 0, 0, 0x100);
+
+			SetNpChar(73, npc->x, npc->y, 2 * Random(-0x200, 0x200), 3 * Random(-0x200, 0x80), 0, 0, 0x100);
+		}
+	}
+
+	RECT rect[2];
+
+	rect[0] = {224, 48, 240, 64};
+	rect[1] = {240, 48, 256, 64};
+
+	npc->rect = rect[npc->ani_no];
+}
+
 //Water droplet
 void ActNpc073(NPCHAR *npc)
 {
@@ -299,4 +431,252 @@
 
 	if (npc->y > gMap.length * 0x10 * 0x200)
 		npc->cond = 0;
+}
+
+// Jack
+void ActNpc074(NPCHAR *npc)
+{
+	RECT rcLeft[6];
+	RECT rcRight[6];
+
+	rcLeft[0] = {64, 0, 80, 16};
+	rcLeft[1] = {80, 0, 96, 16};
+	rcLeft[2] = {96, 0, 112, 16};
+	rcLeft[3] = {64, 0, 80, 16};
+	rcLeft[4] = {112, 0, 128, 16};
+	rcLeft[5] = {64, 0, 80, 16};
+
+	rcRight[0] = {64, 16, 80, 32};
+	rcRight[1] = {80, 16, 96, 32};
+	rcRight[2] = {96, 16, 112, 32};
+	rcRight[3] = {64, 16, 80, 32};
+	rcRight[4] = {112, 16, 128, 32};
+	rcRight[5] = {64, 16, 80, 32};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->ani_no = 0;
+			npc->ani_wait = 0;
+			npc->xm = 0;
+			// Fallthrough
+		case 1:
+			if (Random(0, 120) == 10)
+			{
+				npc->act_no = 2;
+				npc->act_wait = 0;
+				npc->ani_no = 1;
+			}
+
+			break;
+
+		case 2:
+			if (++npc->act_wait > 8)
+			{
+				npc->act_no = 1;
+				npc->ani_no = 0;
+			}
+
+			break;
+
+		case 8:
+			npc->act_no = 9;
+			npc->ani_no = 2;
+			npc->ani_wait = 0;
+			// Fallthrough
+		case 9:
+			if (++npc->ani_wait > 4)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 5)
+				npc->ani_no = 2;
+
+			if (npc->direct)
+				npc->xm = 0x200;
+			else
+				npc->xm = -0x200;
+
+			break;
+	}
+
+	npc->ym += 0x40;
+
+	if (npc->xm > 0x400)
+		npc->xm = 0x400;
+	if (npc->xm < -0x400)
+		npc->xm = -0x400;
+
+	if (npc->ym > 0x5FF)
+		npc->ym = 0x5FF;
+
+	npc->x += npc->xm;
+	npc->y += npc->ym;
+
+	if (npc->direct == 0)
+		npc->rect = rcLeft[npc->ani_no];
+	else
+		npc->rect = rcRight[npc->ani_no];
+}
+
+// Kanpachi (fishing)
+void ActNpc075(NPCHAR *npc)
+{
+	RECT rcLeft[2];
+
+	rcLeft[0].left = 272;
+	rcLeft[0].top = 32;
+	rcLeft[0].right = 296;
+	rcLeft[0].bottom = 56;
+	rcLeft[1].left = 296;
+	rcLeft[1].top = 32;
+	rcLeft[1].right = 320;
+	rcLeft[1].bottom = 56;
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->ani_no = 0;
+			npc->ani_wait = 0;
+			// Fallthrough
+		case 1:
+			if (npc->x - 0x6000 < gMC.x && npc->x + 0x6000 > gMC.x && npc->y - 0x6000 < gMC.y && npc->y + 0x2000 > gMC.y)
+				npc->ani_no = 1;
+			else
+				npc->ani_no = 0;
+
+			break;
+	}
+
+	npc->rect = rcLeft[npc->ani_no];
+}
+
+//Flowers
+void ActNpc076(NPCHAR *npc)
+{
+	npc->rect = {16 * npc->code_event, 0, npc->rect.left + 16, 16};
+}
+
+//Yamashita
+void ActNpc077(NPCHAR *npc)
+{
+	RECT rc[3];
+
+	rc[0] = {0, 16, 48, 48};
+	rc[1] = {48, 16, 96, 48};
+	rc[2] = {96, 16, 144, 48};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->ani_no = 0;
+			npc->ani_wait = 0;
+			// Fallthrough
+		case 1:
+			if (Random(0, 120) == 10)
+			{
+				npc->act_no = 2;
+				npc->act_wait = 0;
+				npc->ani_no = 1;
+			}
+
+			break;
+
+		case 2:
+			if (++npc->act_wait > 8)
+			{
+				npc->act_no = 1;
+				npc->ani_no = 0;
+			}
+
+			break;
+	}
+
+	if (npc->direct == 0)
+		npc->rect = rc[npc->ani_no];
+	else
+		npc->rect = rc[2];
+}
+
+// Pot
+void ActNpc078(NPCHAR *npc)
+{
+	RECT rc[2];
+
+	rc[0] = {160, 48, 176, 64};
+	rc[1] = {176, 48, 192, 64};
+
+	if (npc->direct == 0)
+		npc->rect = rc[0];
+	else
+		npc->rect = rc[1];
+}
+
+// Mahin the sex god
+void ActNpc079(NPCHAR *npc)
+{
+	RECT rcLeft[3];
+	RECT rcRight[3];
+
+	rcLeft[0] = {0, 0, 16, 16};
+	rcLeft[1] = {16, 0, 32, 16};
+	rcLeft[2] = {32, 0, 48, 16};
+
+	rcRight[0] = {0, 16, 16, 32};
+	rcRight[1] = {16, 16, 32, 32};
+	rcRight[2] = {32, 16, 48, 32};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->ani_no = 2;
+			npc->ani_wait = 0;
+			break;
+
+		case 2:
+			npc->ani_no = 0;
+
+			if (Random(0, 120) == 10)
+			{
+				npc->act_no = 3;
+				npc->act_wait = 0;
+				npc->ani_no = 1;
+			}
+
+			if (npc->x - 0x4000 < gMC.x && npc->x + 0x4000 > gMC.x && npc->y - 0x4000 < gMC.y && npc->y + 0x2000 > gMC.y)
+			{
+				if (npc->x <= gMC.x)
+					npc->direct = 2;
+				else
+					npc->direct = 0;
+			}
+
+			break;
+
+		case 3:
+			if (++npc->act_wait > 8 )
+			{
+				npc->act_no = 2;
+				npc->ani_no = 0;
+			}
+
+			break;
+	}
+
+	npc->ym += 0x40;
+	if ( npc->ym > 0x5FF )
+		npc->ym = 0x5FF;
+
+	npc->y += npc->ym;
+
+	if (npc->direct == 0)
+		npc->rect = rcLeft[npc->ani_no];
+	else
+		npc->rect = rcRight[npc->ani_no];
 }
--- /dev/null
+++ b/src/NpcAct080.cpp
@@ -1,0 +1,360 @@
+#include "WindowsWrapper.h"
+
+#include "NpcAct.h"
+
+#include "MyChar.h"
+#include "NpChar.h"
+#include "Game.h"
+#include "Sound.h"
+#include "Back.h"
+#include "Triangle.h"
+#include "Caret.h"
+
+//Igor (cutscene)
+void ActNpc083(NPCHAR *npc)
+{
+	RECT rcLeft[8];
+	RECT rcRight[8];
+
+	rcLeft[0] = {0, 0, 40, 40};
+	rcLeft[1] = {40, 0, 80, 40};
+	rcLeft[2] = {80, 0, 120, 40};
+	rcLeft[3] = {0, 0, 40, 40};
+	rcLeft[4] = {120, 0, 160, 40};
+	rcLeft[5] = {0, 0, 40, 40};
+	rcLeft[6] = {160, 0, 200, 40};
+	rcLeft[7] = {200, 0, 240, 40};
+
+	rcRight[0] = {0, 40, 40, 80};
+	rcRight[1] = {40, 40, 80, 80};
+	rcRight[2] = {80, 40, 120, 80};
+	rcRight[3] = {0, 40, 40, 80};
+	rcRight[4] = {120, 40, 160, 80};
+	rcRight[5] = {0, 40, 40, 80};
+	rcRight[6] = {160, 40, 200, 80};
+	rcRight[7] = {200, 40, 240, 80};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->xm = 0;
+			npc->act_no = 1;
+			npc->ani_no = 0;
+			npc->ani_wait = 0;
+			// Fallthrough
+		case 1:
+			if (++npc->ani_wait > 5)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 1)
+				npc->ani_no = 0;
+
+			break;
+
+		case 2:
+			npc->act_no = 3;
+			npc->ani_no = 2;
+			npc->ani_wait = 0;
+			// Fallthrough
+		case 3:
+			if (++npc->ani_wait > 3)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 5)
+				npc->ani_no = 2;
+
+			if (npc->direct == 0)
+				npc->xm = -0x200;
+			else
+				npc->xm = 0x200;
+
+			break;
+
+		case 4:
+			npc->xm = 0;
+			npc->act_no = 5;
+			npc->act_wait = 0;
+			npc->ani_no = 6;
+			// Fallthrough
+		case 5:
+			if (++npc->act_wait > 10)
+			{
+				npc->act_wait = 0;
+				npc->act_no = 6;
+				npc->ani_no = 7;
+				PlaySoundObject(70, 1);
+			}
+
+			break;
+
+		case 6:
+			if (++npc->act_wait > 8)
+			{
+				npc->act_no = 0;
+				npc->ani_no = 0;
+			}
+
+			break;
+
+		case 7:
+			npc->act_no = 1;
+			break;
+	}
+
+	npc->ym += 0x40;
+	if ( npc->ym > 0x5FF )
+		npc->ym = 0x5FF;
+
+	npc->x += npc->xm;
+	npc->y += npc->ym;
+
+	if (npc->direct == 0)
+		npc->rect = rcLeft[npc->ani_no];
+	else
+		npc->rect = rcRight[npc->ani_no];
+}
+
+//Basu projectile (Egg Corridor)
+void ActNpc084(NPCHAR *npc)
+{
+	if (npc->flag & 0xFF)
+	{
+		SetCaret(npc->x, npc->y, 2, 0);
+		npc->cond = 0;
+	}
+
+	npc->y += npc->ym;
+	npc->x += npc->xm;
+
+	RECT rect_left[4];
+
+	rect_left[0] = {48, 48, 64, 64};
+	rect_left[1] = {64, 48, 80, 64};
+	rect_left[2] = {48, 64, 64, 80};
+	rect_left[3] = {64, 64, 80, 80};
+
+	if (++npc->ani_wait > 2)
+	{
+		npc->ani_wait = 0;
+		++npc->ani_no;
+	}
+
+	if (npc->ani_no > 3)
+		npc->ani_no = 0;
+
+	npc->rect = rect_left[npc->ani_no];
+
+	if (++npc->count1 > 300)
+	{
+		SetCaret(npc->x, npc->y, 2, 0);
+		npc->cond = 0;
+	}
+}
+
+// Terminal
+void ActNpc085(NPCHAR *npc)
+{
+	RECT rcLeft[3];
+	RECT rcRight[3];
+
+	rcLeft[0] = {256, 96, 272, 120};
+	rcLeft[1] = {256, 96, 272, 120};
+	rcLeft[2] = {272, 96, 288, 120};
+
+	rcRight[0] = {256, 96, 272, 120};
+	rcRight[1] = {288, 96, 304, 120};
+	rcRight[2] = {304, 96, 320, 120};
+
+	switch(npc->act_no)
+	{
+		case 0:
+			npc->ani_no = 0;
+
+			if (npc->x - 0x1000 < gMC.x && npc->x + 0x1000 > gMC.x && npc->y - 0x2000 < gMC.y && npc->y + 0x1000 > gMC.y)
+			{
+				PlaySoundObject(43, 1);
+				npc->act_no = 1;
+			}
+
+			break;
+
+		case 1:
+			if (++npc->ani_no > 2)
+				npc->ani_no = 1;
+
+			break;
+	}
+
+	if (npc->direct == 0)
+		npc->rect = rcLeft[npc->ani_no];
+	else
+		npc->rect = rcRight[npc->ani_no];
+}
+
+// Missile
+void ActNpc086(NPCHAR *npc)
+{
+	RECT rect1[2];
+	RECT rect3[2];
+	RECT rcLast[1];
+
+	rect1[0] = {0, 80, 16, 96};
+	rect1[1] = {16, 80, 32, 96};
+
+	rect3[0] = {0, 112, 16, 128};
+	rect3[1] = {16, 112, 32, 128};
+
+	rcLast[0] = {16, 0, 32, 16};
+
+	if (npc->direct == 0)
+	{
+		if (++npc->ani_wait > 2)
+		{
+			npc->ani_wait = 0;
+			++npc->ani_no;
+		}
+
+		if (npc->ani_no > 1)
+			npc->ani_no = 0;
+	}
+
+	if (gBack.type == 5 || gBack.type == 6)
+	{
+		if (npc->act_no == 0)
+		{
+			npc->act_no = 1;
+			npc->ym = Random(-0x20, 0x20);
+			npc->xm = Random(0x7F, 0x100);
+		}
+
+		npc->xm -= 8;
+
+		if (npc->x < 0xA000)
+			npc->cond = 0;
+
+		if (npc->x < -0x600)
+			npc->x = -0x600;
+
+		if (npc->flag & 1)
+			npc->xm = 0x100;
+
+		if (npc->flag & 2)
+			npc->ym = 0x40;
+
+		if (npc->flag & 8)
+			npc->ym = -0x40;
+
+		npc->x += npc->xm;
+		npc->y += npc->ym;
+	}
+
+	switch (npc->exp)
+	{
+		case 1:
+			npc->rect = rect1[npc->ani_no];
+			break;
+
+		case 3:
+			npc->rect = rect3[npc->ani_no];
+			break;
+	}
+
+	if (npc->direct == 0)
+		++npc->count1;
+
+	if (npc->count1 > 550)
+		npc->cond = 0;
+
+	if (npc->count1 > 500 && npc->count1 / 2 % 2)
+		npc->rect.right = 0;
+
+	if (npc->count1 > 547)
+		npc->rect = rcLast[0];;
+}
+
+// Heart
+void ActNpc087(NPCHAR *npc)
+{
+	RECT rect2[5];
+	RECT rect6[2];
+	RECT rcLast[1];
+
+	rect2[0] = {32, 80, 48, 96};
+	rect2[1] = {48, 80, 64, 96};
+
+	rect6[0] = {64, 80, 80, 96};
+	rect6[1] = {80, 80, 96, 96};
+
+	rcLast[0] = {16, 0, 32, 16};
+
+	if (npc->direct == 0)
+	{
+		if (++npc->ani_wait > 2)
+		{
+			npc->ani_wait = 0;
+			++npc->ani_no;
+		}
+
+		if (npc->ani_no > 1)
+			npc->ani_no = 0;
+	}
+
+	if (gBack.type == 5 || gBack.type == 6)
+	{
+		if (npc->act_no == 0)
+		{
+			npc->act_no = 1;
+			npc->ym = Random(-0x20, 0x20);
+			npc->xm = Random(0x7F, 0x100);
+		}
+
+		npc->xm -= 8;
+
+		if (npc->x < 0xA000)
+			npc->cond = 0;
+
+		if (npc->x < -0x600)
+			npc->x = -0x600;
+
+		if (npc->flag & 1)
+			npc->xm = 0x100;
+
+		if (npc->flag & 2)
+			npc->ym = 0x40;
+
+		if (npc->flag & 8)
+			npc->ym = -0x40;
+
+		npc->x += npc->xm;
+		npc->y += npc->ym;
+	}
+
+	switch (npc->exp)
+	{
+		case 2:
+			npc->rect = rect2[npc->ani_no];
+			break;
+
+		case 6:
+			npc->rect = rect6[npc->ani_no];
+			break;
+	}
+
+	if (npc->direct == 0)
+		++npc->count1;
+
+	if (npc->count1 > 550)
+		npc->cond = 0;
+
+	if (npc->count1 > 500 && npc->count1 / 2 % 2)
+		npc->rect.right = 0;
+
+	if (npc->count1 > 547)
+		npc->rect = rcLast[0];
+}
--- a/src/NpcAct100.cpp
+++ b/src/NpcAct100.cpp
@@ -9,6 +9,16 @@
 #include "Back.h"
 #include "Triangle.h"
 
+//Red petals
+void ActNpc116(NPCHAR *npc)
+{
+	RECT rc[1];
+
+	rc[0] = {272, 184, 320, 200};
+
+	npc->rect = rc[0];
+}
+
 //Table and chair
 void ActNpc119(NPCHAR *npc)
 {
--- /dev/null
+++ b/src/NpcAct120.cpp
@@ -1,0 +1,37 @@
+#include "WindowsWrapper.h"
+
+#include "NpcAct.h"
+
+#include "MyChar.h"
+#include "NpChar.h"
+#include "Game.h"
+#include "Sound.h"
+#include "Back.h"
+#include "Triangle.h"
+
+//Hidden item
+void ActNpc125(NPCHAR *npc)
+{
+	if (npc->life < 990)
+	{
+		SetDestroyNpChar(npc->x, npc->y, npc->view.back, 8);
+		PlaySoundObject(70, 1);
+
+		if (npc->direct)
+			SetNpChar(86, npc->x, npc->y, 0, 0, 2, 0, 0);
+		else
+			SetNpChar(87, npc->x, npc->y, 0, 0, 2, 0, 0);
+
+		npc->cond = 0;
+	}
+
+	RECT rc[2];
+
+	rc[0] = {0, 96, 16, 112};
+	rc[1] = {16, 96, 32, 112};
+
+	if (npc->direct == 0)
+		npc->rect = rc[0];
+	else
+		npc->rect = rc[1];
+}
--- /dev/null
+++ b/src/NpcAct140.cpp
@@ -1,0 +1,56 @@
+#include "WindowsWrapper.h"
+
+#include "NpcAct.h"
+
+#include "MyChar.h"
+#include "NpChar.h"
+#include "Game.h"
+#include "Sound.h"
+#include "Back.h"
+#include "Triangle.h"
+
+//Blue robot (standing)
+void ActNpc151(NPCHAR *npc)
+{
+	RECT rcLeft[2];
+	RECT rcRight[2];
+
+	rcLeft[0] = {192, 0, 208, 16};
+	rcLeft[1] = {208, 0, 224, 16};
+
+	rcRight[0] = {192, 16, 208, 32};
+	rcRight[1] = {208, 16, 224, 32};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->ani_no = 0;
+			npc->ani_wait = 0;
+			// Fallthrough
+
+		case 1:
+			if (Random(0, 100) == 0)
+			{
+				npc->act_no = 2;
+				npc->act_wait = 0;
+				npc->ani_no = 1;
+			}
+
+			break;
+
+		case 2:
+			if (++npc->act_wait > 16)
+			{
+				npc->act_no = 1;
+				npc->ani_no = 0;
+			}
+
+			break;
+	}
+
+	if (npc->direct == 0)
+		npc->rect = rcLeft[npc->ani_no];
+	else
+		npc->rect = rcRight[npc->ani_no];
+}
--- a/src/NpcTbl.cpp
+++ b/src/NpcTbl.cpp
@@ -63,6 +63,8 @@
 	ActNpc004,
 	ActNpc005,
 	ActNpc006,
+	ActNpc007,
+	ActNpc008,
 	nullptr,
 	nullptr,
 	nullptr,
@@ -69,8 +71,6 @@
 	nullptr,
 	nullptr,
 	nullptr,
-	nullptr,
-	nullptr,
 	ActNpc015,
 	ActNpc016,
 	ActNpc017,
@@ -81,25 +81,28 @@
 	ActNpc022,
 	ActNpc023,
 	nullptr,
+	ActNpc025,
 	nullptr,
 	nullptr,
 	nullptr,
-	nullptr,
-	nullptr,
+	ActNpc029,
 	ActNpc030,
 	nullptr,
 	ActNpc032,
 	nullptr,
+	ActNpc034,
 	nullptr,
 	nullptr,
-	nullptr,
 	ActNpc037,
 	nullptr,
 	ActNpc039,
 	nullptr,
 	nullptr,
+	ActNpc042,
+	ActNpc043,
 	nullptr,
 	nullptr,
+	ActNpc046,
 	nullptr,
 	nullptr,
 	nullptr,
@@ -111,10 +114,7 @@
 	nullptr,
 	nullptr,
 	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
+	ActNpc058,
 	ActNpc059,
 	nullptr,
 	nullptr,
@@ -126,13 +126,24 @@
 	nullptr,
 	nullptr,
 	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
+	ActNpc070,
+	ActNpc071,
+	ActNpc072,
 	ActNpc073,
+	ActNpc074,
+	ActNpc075,
+	ActNpc076,
+	ActNpc077,
+	ActNpc078,
+	ActNpc079,
 	nullptr,
 	nullptr,
 	nullptr,
+	ActNpc083,
+	ActNpc084,
+	ActNpc085,
+	ActNpc086,
+	ActNpc087,
 	nullptr,
 	nullptr,
 	nullptr,
@@ -161,20 +172,9 @@
 	nullptr,
 	nullptr,
 	nullptr,
+	ActNpc116,
 	nullptr,
 	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
 	ActNpc119,
 	nullptr,
 	nullptr,
@@ -181,6 +181,7 @@
 	nullptr,
 	nullptr,
 	nullptr,
+	ActNpc125,
 	nullptr,
 	nullptr,
 	nullptr,
@@ -206,8 +207,7 @@
 	nullptr,
 	nullptr,
 	nullptr,
-	nullptr,
-	nullptr,
+	ActNpc151,
 	nullptr,
 	nullptr,
 	nullptr,
--- a/src/Organya.cpp
+++ b/src/Organya.cpp
@@ -78,7 +78,11 @@
 	{
 		if(info.tdata[i].note_p != NULL)
 		{
+#ifdef FIX_BUGS
+			delete[] info.tdata[i].note_p;
+#else
 			delete info.tdata[i].note_p;	// should be delete[]
+#endif
 			info.tdata[i].note_p = NULL;
 		}
 	}