From cd276d94be13523c97054f3b7e4b438562ea9292 Mon Sep 17 00:00:00 2001 From: Clownacy Date: Mon, 28 Jan 2019 20:50:26 +0000 Subject: [PATCH 01/10] Fix possible bug in CortBox2 Cppcheck was complaining about duplicate conditions --- src/Draw.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Draw.cpp b/src/Draw.cpp index 27d6b6f0..40dbbe8e 100644 --- a/src/Draw.cpp +++ b/src/Draw.cpp @@ -375,8 +375,8 @@ void CortBox2(RECT *rect, uint32_t col, int surf_no) 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; From d33f4b1b5165306832c88ce2fd9a327f439d0375 Mon Sep 17 00:00:00 2001 From: Clownacy Date: Tue, 29 Jan 2019 07:36:28 +0000 Subject: [PATCH 02/10] Use FIX_BUGS to fix that one delete[] bug in Organya Fixes #31 --- src/Organya.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Organya.cpp b/src/Organya.cpp index 99cf654c..3ce94914 100644 --- a/src/Organya.cpp +++ b/src/Organya.cpp @@ -78,7 +78,11 @@ void OrganyaReleaseNote() { 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; } } From 8fd92fb19734da7182ac5afc4f16f63e5dbadf87 Mon Sep 17 00:00:00 2001 From: Clownacy Date: Tue, 29 Jan 2019 07:41:32 +0000 Subject: [PATCH 03/10] Fixed incorrect format specifier in bin2h Fixes #27 --- res/bin2h.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/bin2h.c b/res/bin2h.c index af8fb8e8..06ca5a6a 100644 --- a/res/bin2h.c +++ b/res/bin2h.c @@ -50,7 +50,7 @@ int main(int argc, char *argv[]) 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) { From 004d5adf7bef6f20e05b5df6a7b76eceeb9c620c Mon Sep 17 00:00:00 2001 From: Clownacy Date: Tue, 29 Jan 2019 07:45:07 +0000 Subject: [PATCH 04/10] Correct typo in gMC.equip assignment Fixes #29 --- src/Game.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Game.cpp b/src/Game.cpp index f0da9a46..9d169d54 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -284,7 +284,7 @@ int ModeTitle() //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; From 90ef30becef2e3ff4bdbaf3f3abd2ad9517d7802 Mon Sep 17 00:00:00 2001 From: Clownacy Date: Tue, 29 Jan 2019 10:18:34 +0000 Subject: [PATCH 05/10] Added option for fonts to be loaded from Windows This restores some compatibility with Config.dat's font settings. --- Makefile | 8 +- src/Draw.cpp | 81 ++++++++++++- src/Draw.h | 2 +- src/Font.cpp | 312 +++++++++++++++++++++++++++++---------------------- src/Font.h | 3 +- src/Main.cpp | 2 +- 6 files changed, 264 insertions(+), 144 deletions(-) diff --git a/Makefile b/Makefile index 587c5bec..12698bfd 100644 --- a/Makefile +++ b/Makefile @@ -20,8 +20,12 @@ ifeq ($(FIX_BUGS), 1) 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` diff --git a/src/Draw.cpp b/src/Draw.cpp index 40dbbe8e..de06a8ec 100644 --- a/src/Draw.cpp +++ b/src/Draw.cpp @@ -4,6 +4,18 @@ #include #include +#ifdef WINDOWS +#define RECT WINRECT +#define FindResource WinFindResource // All these damn name collisions... +#define DrawText WinDrawText +#define LoadFont WinLoadFont +#include +#undef LoadFont +#undef DrawText +#undef FindResource +#undef RECT +#endif + #include #include #include @@ -388,7 +400,54 @@ void CortBox2(RECT *rect, uint32_t col, int surf_no) 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; @@ -403,6 +462,24 @@ void InitTextObject() 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 @@ void InitTextObject() 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) diff --git a/src/Draw.h b/src/Draw.h index 580cf37a..9305b816 100644 --- a/src/Draw.h +++ b/src/Draw.h @@ -66,7 +66,7 @@ void PutBitmap4(RECT *rcView, int x, int y, RECT *rect, int surf_no); 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(); diff --git a/src/Font.cpp b/src/Font.cpp index e0875146..fa097b8d 100644 --- a/src/Font.cpp +++ b/src/Font.cpp @@ -2,7 +2,9 @@ #include #include +#include #include +#include #ifdef JAPANESE #include @@ -27,6 +29,7 @@ typedef struct FontObject { FT_Library library; FT_Face face; + unsigned char *data; #ifndef DISABLE_FONT_ANTIALIASING bool lcd_mode; #endif @@ -89,7 +92,7 @@ static unsigned long UTF8ToCode(const unsigned char *string, unsigned int *bytes 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 @@ FontObject* LoadFont(unsigned int cell_width, unsigned int cell_height, char *fo 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); + + 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_cell_width = 0; - unsigned int best_cell_height = 0; unsigned int best_pixel_width = 0; unsigned int best_pixel_height = 0; @@ -120,15 +132,10 @@ FontObject* LoadFont(unsigned int cell_width, unsigned int cell_height, char *fo 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 @@ FontObject* LoadFont(unsigned int cell_width, unsigned int cell_height, char *fo 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) +FontObject* LoadFont(const char *font_filename, unsigned int cell_width, unsigned int cell_height) { - const unsigned char colours[3] = {(unsigned char)(colour >> 16), (unsigned char)(colour >> 8), (unsigned char)colour}; + FontObject *font_object = NULL; - SDL_Texture *old_render_target = SDL_GetRenderTarget(renderer); - SDL_SetRenderTarget(renderer, texture); + FILE *file = fopen(font_filename, "rb"); - 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; - - FT_Face face = font_object->face; - - unsigned int pen_x = 0; - - const unsigned char *string_pointer = (unsigned char*)string; - const unsigned char *string_end = (unsigned char*)string + string_length; - - while (string_pointer != string_end) + if (file != NULL) { -#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; + 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); - 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; + font_object = LoadFontFromData(file_buffer, file_size, cell_width, cell_height); - 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); - - 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; -#endif - - 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)); -#else - 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); - - 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 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]; - - if (font_pixel[0] || font_pixel[1] || font_pixel[2]) - { - 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; - } - } - } - 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) - { - 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 - - 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 - - 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) - { - unsigned char (*font_buffer)[converted.pitch] = (unsigned char (*)[converted.pitch])converted.buffer; - - 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]; - - surface_pixel[3] = 0xFF; - } - } - } - } - - FT_Bitmap_Done(font_object->library, &converted); - - pen_x += face->glyph->advance.x / 64; + free(file_buffer); } - 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); + 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) +{ + 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); + + 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; + + FT_Face face = font_object->face; + + unsigned int pen_x = 0; + + const unsigned char *string_pointer = (unsigned char*)string; + const unsigned char *string_end = (unsigned char*)string + string_length; + + 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 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]; + + string_pointer += in_size; + + 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; +#endif + + 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)); +#else + 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); + + 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 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]; + + if (font_pixel[0] || font_pixel[1] || font_pixel[2]) + { + 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; + } + } + } + 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) + { + 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 + + 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 + + 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) + { + unsigned char (*font_buffer)[converted.pitch] = (unsigned char (*)[converted.pitch])converted.buffer; + + 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]; + + surface_pixel[3] = 0xFF; + } + } + } + } + + FT_Bitmap_Done(font_object->library, &converted); + + 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); + } } 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); + } } diff --git a/src/Font.h b/src/Font.h index 89a2adb3..fbd7ddc4 100644 --- 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); diff --git a/src/Main.cpp b/src/Main.cpp index 2afe2b38..a47c7bcc 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -284,7 +284,7 @@ int main(int argc, char *argv[]) } //Initialize stuff - InitTextObject(); + InitTextObject(config.font_name); InitTriangleTable(); //Run game code From 05a71c8eb8824160f1a2ff5225cfc1f0a1de694e Mon Sep 17 00:00:00 2001 From: Clownacy Date: Tue, 29 Jan 2019 15:07:29 +0000 Subject: [PATCH 06/10] Fixed mini-map --- src/MiniMap.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/MiniMap.cpp b/src/MiniMap.cpp index 103b2502..d109feb3 100644 --- a/src/MiniMap.cpp +++ b/src/MiniMap.cpp @@ -21,15 +21,13 @@ void WriteMiniMapLine(int line) 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: @@ -106,7 +104,7 @@ int MiniMapLoop() 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); From 81f22c2bb863a12fe4a8ac57ace5e08a01513c4c Mon Sep 17 00:00:00 2001 From: Clownacy Date: Tue, 29 Jan 2019 18:48:43 +0000 Subject: [PATCH 07/10] Added more NPCs Mostly, if not all, Egg Corridor. --- Makefile | 2 + src/NpChar.cpp | 3 + src/NpChar.h | 3 + src/NpcAct.h | 13 +- src/NpcAct000.cpp | 100 ++++++++++ src/NpcAct040.cpp | 475 ++++++++++++++++++++++++++++++++++++++++++++++ src/NpcTbl.cpp | 18 +- 7 files changed, 603 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index 12698bfd..17680777 100644 --- a/Makefile +++ b/Makefile @@ -65,7 +65,9 @@ SOURCES = \ NpcAct020 \ NpcAct040 \ NpcAct060 \ + NpcAct080 \ NpcAct100 \ + NpcAct140 \ NpcAct200 \ NpcAct280 \ NpcAct300 \ diff --git a/src/NpChar.cpp b/src/NpChar.cpp index 88a7d80a..0b54d2d1 100644 --- 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() diff --git a/src/NpChar.h b/src/NpChar.h index bfe3fb68..3180c13a 100644 --- a/src/NpChar.h +++ b/src/NpChar.h @@ -73,6 +73,9 @@ struct EVENT 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); diff --git a/src/NpcAct.h b/src/NpcAct.h index 8c50ce08..e722fb38 100644 --- a/src/NpcAct.h +++ b/src/NpcAct.h @@ -10,6 +10,8 @@ void ActNpc004(NPCHAR *npc); void ActNpc005(NPCHAR *npc); void ActNpc006(NPCHAR *npc); +void ActNpc008(NPCHAR *npc); + void ActNpc015(NPCHAR *npc); void ActNpc016(NPCHAR *npc); void ActNpc017(NPCHAR *npc); @@ -28,19 +30,26 @@ void ActNpc037(NPCHAR *npc); void ActNpc039(NPCHAR *npc); +void ActNpc042(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 ActNpc073(NPCHAR *npc); +void ActNpc083(NPCHAR *npc); + void ActNpc119(NPCHAR *npc); +void ActNpc151(NPCHAR *npc); + void ActNpc211(NPCHAR *npc); void ActNpc298(NPCHAR *npc); diff --git a/src/NpcAct000.cpp b/src/NpcAct000.cpp index 641b7306..ef4de2c8 100644 --- a/src/NpcAct000.cpp +++ b/src/NpcAct000.cpp @@ -620,6 +620,106 @@ void ActNpc006(NPCHAR *npc) npc->rect = rcLeft[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) { diff --git a/src/NpcAct040.cpp b/src/NpcAct040.cpp index 3b58c384..8bc7d61e 100644 --- a/src/NpcAct040.cpp +++ b/src/NpcAct040.cpp @@ -9,6 +9,481 @@ #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]; +} + +// 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) { diff --git a/src/NpcTbl.cpp b/src/NpcTbl.cpp index d4631d08..bbd33746 100644 --- a/src/NpcTbl.cpp +++ b/src/NpcTbl.cpp @@ -64,7 +64,7 @@ NPCFUNCTION gpNpcFuncTbl[361] = ActNpc005, ActNpc006, nullptr, - nullptr, + ActNpc008, nullptr, nullptr, nullptr, @@ -98,6 +98,11 @@ NPCFUNCTION gpNpcFuncTbl[361] = ActNpc039, nullptr, nullptr, + ActNpc042, + nullptr, + nullptr, + nullptr, + ActNpc046, nullptr, nullptr, nullptr, @@ -109,12 +114,7 @@ NPCFUNCTION gpNpcFuncTbl[361] = nullptr, nullptr, nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, + ActNpc058, ActNpc059, nullptr, nullptr, @@ -139,7 +139,7 @@ NPCFUNCTION gpNpcFuncTbl[361] = nullptr, nullptr, nullptr, - nullptr, + ActNpc083, nullptr, nullptr, nullptr, @@ -207,7 +207,7 @@ NPCFUNCTION gpNpcFuncTbl[361] = nullptr, nullptr, nullptr, - nullptr, + ActNpc151, nullptr, nullptr, nullptr, From 76cb99342ac7b5c3c019a593f1bef18307a442e7 Mon Sep 17 00:00:00 2001 From: Clownacy Date: Tue, 29 Jan 2019 18:55:20 +0000 Subject: [PATCH 08/10] Finished MiniMapLoop --- src/MiniMap.cpp | 52 +++++++++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/src/MiniMap.cpp b/src/MiniMap.cpp index d109feb3..8bae1934 100644 --- a/src/MiniMap.cpp +++ b/src/MiniMap.cpp @@ -101,7 +101,7 @@ int MiniMapLoop() PutFramePerSecound(); if (!Flip_SystemTask()) - return 0; + return 0; } RECT rcMiniMap = {0, 0, gMap.width, gMap.length}; @@ -145,30 +145,32 @@ int MiniMapLoop() if (!Flip_SystemTask()) return 0; } - /* - for ( f = 8; f >= -1; --f ) - { - GetTrg(); - if ( gKey & 0x8000 ) - { - v3 = Call_Escape(gscreen); - if ( !v3 ) - return 0; - if ( v3 == 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(1); - CortBox(&rcView, 0); - PutFramePerSecound(); - if ( !Flip_SystemTask(gscreen) ) - return 0; - } - */ + for (int f = 8; f >= -1; --f) + { + 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; + } + return 1; } \ No newline at end of file From 25b58cc07200530ceed8f6bde8dd471b771a8311 Mon Sep 17 00:00:00 2001 From: Clownacy Date: Tue, 29 Jan 2019 20:12:49 +0000 Subject: [PATCH 09/10] More NPCs --- Makefile | 1 + src/NpcAct.h | 15 +- src/NpcAct000.cpp | 82 +++++++++++ src/NpcAct020.cpp | 175 ++++++++++++++++++++++ src/NpcAct080.cpp | 360 ++++++++++++++++++++++++++++++++++++++++++++++ src/NpcAct100.cpp | 10 ++ src/NpcAct120.cpp | 37 +++++ src/NpcAct140.cpp | 56 ++++++++ src/NpcTbl.cpp | 20 +-- 9 files changed, 745 insertions(+), 11 deletions(-) create mode 100644 src/NpcAct080.cpp create mode 100644 src/NpcAct120.cpp create mode 100644 src/NpcAct140.cpp diff --git a/Makefile b/Makefile index 17680777..cb058fd9 100644 --- a/Makefile +++ b/Makefile @@ -67,6 +67,7 @@ SOURCES = \ NpcAct060 \ NpcAct080 \ NpcAct100 \ + NpcAct120 \ NpcAct140 \ NpcAct200 \ NpcAct280 \ diff --git a/src/NpcAct.h b/src/NpcAct.h index e722fb38..8ca36c81 100644 --- a/src/NpcAct.h +++ b/src/NpcAct.h @@ -9,7 +9,7 @@ void ActNpc003(NPCHAR *npc); void ActNpc004(NPCHAR *npc); void ActNpc005(NPCHAR *npc); void ActNpc006(NPCHAR *npc); - +void ActNpc007(NPCHAR *npc); void ActNpc008(NPCHAR *npc); void ActNpc015(NPCHAR *npc); @@ -22,10 +22,15 @@ void ActNpc021(NPCHAR *npc); 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); @@ -45,9 +50,17 @@ void ActNpc065(NPCHAR *npc); void ActNpc073(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); diff --git a/src/NpcAct000.cpp b/src/NpcAct000.cpp index ef4de2c8..52ec9f45 100644 --- a/src/NpcAct000.cpp +++ b/src/NpcAct000.cpp @@ -620,6 +620,88 @@ void ActNpc006(NPCHAR *npc) 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) { diff --git a/src/NpcAct020.cpp b/src/NpcAct020.cpp index 4a45ea6e..046db7fd 100644 --- a/src/NpcAct020.cpp +++ b/src/NpcAct020.cpp @@ -108,6 +108,166 @@ void ActNpc023(NPCHAR *npc) 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) { @@ -188,6 +348,21 @@ void ActNpc032(NPCHAR *npc) 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 void ActNpc037(NPCHAR *npc) { diff --git a/src/NpcAct080.cpp b/src/NpcAct080.cpp new file mode 100644 index 00000000..7855b0db --- /dev/null +++ b/src/NpcAct080.cpp @@ -0,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]; +} diff --git a/src/NpcAct100.cpp b/src/NpcAct100.cpp index 3c4b8f2f..43a1cb9f 100644 --- 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) { diff --git a/src/NpcAct120.cpp b/src/NpcAct120.cpp new file mode 100644 index 00000000..edb47580 --- /dev/null +++ b/src/NpcAct120.cpp @@ -0,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]; +} diff --git a/src/NpcAct140.cpp b/src/NpcAct140.cpp new file mode 100644 index 00000000..232a4857 --- /dev/null +++ b/src/NpcAct140.cpp @@ -0,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]; +} diff --git a/src/NpcTbl.cpp b/src/NpcTbl.cpp index bbd33746..6460b705 100644 --- a/src/NpcTbl.cpp +++ b/src/NpcTbl.cpp @@ -63,7 +63,7 @@ NPCFUNCTION gpNpcFuncTbl[361] = ActNpc004, ActNpc005, ActNpc006, - nullptr, + ActNpc007, ActNpc008, nullptr, nullptr, @@ -81,16 +81,16 @@ NPCFUNCTION gpNpcFuncTbl[361] = ActNpc022, ActNpc023, nullptr, + ActNpc025, nullptr, nullptr, nullptr, - nullptr, - nullptr, + ActNpc029, ActNpc030, nullptr, ActNpc032, nullptr, - nullptr, + ActNpc034, nullptr, nullptr, ActNpc037, @@ -140,6 +140,10 @@ NPCFUNCTION gpNpcFuncTbl[361] = nullptr, nullptr, ActNpc083, + ActNpc084, + ActNpc085, + ActNpc086, + ActNpc087, nullptr, nullptr, nullptr, @@ -168,11 +172,7 @@ NPCFUNCTION gpNpcFuncTbl[361] = nullptr, nullptr, nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, + ActNpc116, nullptr, nullptr, ActNpc119, @@ -181,7 +181,7 @@ NPCFUNCTION gpNpcFuncTbl[361] = nullptr, nullptr, nullptr, - nullptr, + ActNpc125, nullptr, nullptr, nullptr, From 51a11eede1a5f17d6174fdf5e62f427f42a637ba Mon Sep 17 00:00:00 2001 From: Clownacy Date: Tue, 29 Jan 2019 21:38:45 +0000 Subject: [PATCH 10/10] More NPCs Moving onto Mimiga Village --- src/NpcAct.h | 10 ++ src/NpcAct040.cpp | 23 ++- src/NpcAct060.cpp | 380 ++++++++++++++++++++++++++++++++++++++++++++++ src/NpcTbl.cpp | 20 +-- 4 files changed, 422 insertions(+), 11 deletions(-) diff --git a/src/NpcAct.h b/src/NpcAct.h index 8ca36c81..90677526 100644 --- a/src/NpcAct.h +++ b/src/NpcAct.h @@ -36,6 +36,7 @@ void ActNpc037(NPCHAR *npc); void ActNpc039(NPCHAR *npc); void ActNpc042(NPCHAR *npc); +void ActNpc043(NPCHAR *npc); void ActNpc046(NPCHAR *npc); @@ -47,7 +48,16 @@ void ActNpc062(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); diff --git a/src/NpcAct040.cpp b/src/NpcAct040.cpp index 8bc7d61e..2a29ebd0 100644 --- a/src/NpcAct040.cpp +++ b/src/NpcAct040.cpp @@ -294,7 +294,28 @@ void ActNpc042(NPCHAR *npc) npc->rect = rcRight[npc->ani_no]; } -// H/V Trigger +//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]; diff --git a/src/NpcAct060.cpp b/src/NpcAct060.cpp index 3522bcba..04acf303 100644 --- 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 @@ void ActNpc065(NPCHAR *npc) 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) { @@ -300,3 +432,251 @@ void ActNpc073(NPCHAR *npc) 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]; +} diff --git a/src/NpcTbl.cpp b/src/NpcTbl.cpp index 6460b705..61e54126 100644 --- a/src/NpcTbl.cpp +++ b/src/NpcTbl.cpp @@ -99,7 +99,7 @@ NPCFUNCTION gpNpcFuncTbl[361] = nullptr, nullptr, ActNpc042, - nullptr, + ActNpc043, nullptr, nullptr, ActNpc046, @@ -126,16 +126,16 @@ NPCFUNCTION gpNpcFuncTbl[361] = nullptr, nullptr, nullptr, - nullptr, - nullptr, - nullptr, + ActNpc070, + ActNpc071, + ActNpc072, ActNpc073, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, + ActNpc074, + ActNpc075, + ActNpc076, + ActNpc077, + ActNpc078, + ActNpc079, nullptr, nullptr, nullptr,