From 96bb9ea7891bfbf1fff118b99dcc34c2c55a3159 Mon Sep 17 00:00:00 2001 From: Michael Schwartz Date: Sun, 1 Nov 2020 12:22:30 -0800 Subject: [PATCH 1/6] cleanups --- Evade2/src/Font.cpp | 421 ------------------------------ Evade2/src/Font.h | 32 --- Evade2/src/Game.h | 2 + Evade2/src/common/GVectorFont.cpp | 365 ++++++++++++++++++++++++++ Evade2/src/common/GVectorFont.h | 22 ++ Evade2/src/{ => common}/charset.h | 126 +++++---- 6 files changed, 451 insertions(+), 517 deletions(-) delete mode 100644 Evade2/src/Font.cpp delete mode 100644 Evade2/src/Font.h create mode 100644 Evade2/src/common/GVectorFont.cpp create mode 100644 Evade2/src/common/GVectorFont.h rename Evade2/src/{ => common}/charset.h (85%) diff --git a/Evade2/src/Font.cpp b/Evade2/src/Font.cpp deleted file mode 100644 index 3bd1fdf..0000000 --- a/Evade2/src/Font.cpp +++ /dev/null @@ -1,421 +0,0 @@ -#define DEBUGME - -/** - * Some of this code lifted from Arduino serial Print class and modified. - * See: - * https://github.com/arduino/Arduino/blob/master/hardware/arduino/avr/cores/arduino/Print.cpp - */ - -#include "Font.h" -#include "charset.h" - -#include -#include - -#ifdef MIKE_REMOVED_THHIS -static TInt8 *pgm_read_TInt16(const void *addr) { - const TUint16 *p = (const TUint16 *)addr; - return (TInt8 *)*p; -} -#endif - -static const TInt8 *charset[] = { - ENull, // space - font_emark, -#ifdef FULL_CHARSET - font_dquote, -#else - ENull, -#endif -#ifdef FULL_CHARSET - font_pound, // # -#else - ENull, -#endif -#ifdef FULL_CHARSET - font_dollar, // $ -#else - ENull, -#endif -#ifdef FULL_CHARSET - font_percent, // % -#else - ENull, -#endif -#ifdef FULL_CHARSET - font_amp, // & -#else - ENull, -#endif -#ifdef FULL_CHARSET - font_squote, // ' -#else - ENull, -#endif -#ifdef FULL_CHARSET - font_lparen, // ( -#else - ENull, -#endif -#ifdef FULL_CHARSET - font_rparen, // ) -#else - ENull, -#endif -#ifdef FULL_CHARSET - font_asterisk, // * -#else - ENull, -#endif -#ifdef FULL_CHARSET - font_plus, -#else - ENull, -#endif -#ifdef FULL_CHARSET - font_comma, -#else - ENull, -#endif -#ifdef FULL_CHARSET - font_minus, -#else - ENull, -#endif - font_period, font_fslash, font_0, font_1, font_2, font_3, font_4, - font_5, font_6, font_7, font_8, font_9, font_colon, -#ifdef FULL_CHARSET - font_semicolon, -#else - ENull, -#endif -#ifdef FULL_CHARSET - font_lt, // < -#else - ENull, -#endif -#ifdef FULL_CHARSET - font_eq, // = -#else - ENull, -#endif -#ifdef FULL_CHARSET - font_gt, // > -#else - ENull, -#endif -#ifdef FULL_CHARSET - font_qmark, -#else - ENull, -#endif -#ifdef FULL_CHARSET - font_at, // @ -#else - ENull, -#endif - font_a, font_b, font_c, font_d, font_e, font_f, font_g, - font_h, font_i, font_j, font_k, font_l, font_m, font_n, - font_o, font_p, font_q, font_r, font_s, font_t, font_u, - font_v, font_w, font_x, font_y, font_z, -#ifdef FULL_CHARSET - font_lt, // [ -#else - ENull, -#endif -#ifdef FULL_CHARSET - font_bslash, // '\' -#else - ENull, -#endif -#ifdef FULL_CHARSET - font_gt, // ] -#else - ENull, -#endif -#ifdef FULL_CHARSET - font_caret, // ^ -#else - ENull, -#endif -#ifdef FULL_CHARSET - font_uscore, // _ -#else - ENull, -#endif - ENull, // `` -}; - -TInt16 Font::scale = 0x100; - -TInt8 Font::print_string_rotatedx(TUint8 color, TInt16 x, TInt16 y, TFloat theta, const char *p) { - theta = TFloat(theta) * 3.1415926 / 180; - TFloat cost = cos(theta), sint = sin(theta); - - TFloat fscale = TFloat(scale >> 8) + TFloat(scale & 0xff) / 256.0; - - const TInt8 size = 9; - - TInt8 xo = x; - while (char c = *p++) { - const TInt8 *glyph = charset[toupper(c) - 32]; - if (glyph) { - TInt8 lines = *glyph++; - - for (TInt8 i = 0; i < lines; i++) { - TFloat x0 = (TInt8)*glyph++ * fscale + x, - y0 = (TInt8)*glyph++ * fscale + y, - x1 = (TInt8)*glyph++ * fscale + x, - y1 = (TInt8)*glyph++ * fscale + y; - - gDisplay.renderBitmap->DrawLine(ENull,x0, ((y0 - y) * sint + cost + y), x1, - ((y1 - y) * sint + cost + y), color); - } - x += size * fscale; - } else { - x += 6 * fscale; - } - } - return x - xo; -} - -TInt8 Font::print_string_rotatedx(TInt16 x, TInt16 y, TFloat theta, const char *p) { - theta = TFloat(theta) * 3.1415926 / 180; - TFloat cost = cos(theta), sint = sin(theta); - - TFloat fscale = TFloat(scale >> 8) + TFloat(scale & 0xff) / 256.0; - - const TInt8 size = 9; - - TInt8 xo = x; - while (char c = *p++) { - const TInt8 *glyph = charset[toupper(c) - 32]; - if (glyph) { - TInt8 lines = *glyph++; - - for (TInt8 i = 0; i < lines; i++) { - TFloat x0 = (TInt8)*glyph++ * fscale + x, - y0 = (TInt8)*glyph++ * fscale + y, - x1 = (TInt8)*glyph++ * fscale + x, - y1 = (TInt8)*glyph++ * fscale + y; - - gDisplay.renderBitmap->DrawLine(ENull,x0, ((y0 - y) * sint + cost + y), x1, - ((y1 - y) * sint + cost + y), SHMOO_COLOR); - } - x += size * fscale; - } else { - x += 6 * fscale; - } - } - return x - xo; -} - -TInt8 Font::write(TUint8 color, TInt16 x, TInt16 y, char c) { - const TInt8 *glyph; - const TInt8 width = 9; - - TFloat fscale = TFloat(scale >> 8) + TFloat(scale & 0xff) / 256.0; - - glyph = charset[toupper(c) - 32]; - // ::printf("write %x\n", palette[COLOR_RED]); - // ::printf("c %c glyph %lx charset %lx\n", c, (long)glyph, (long)charset); - if (glyph) { - TInt8 lines = *glyph++; - - for (TInt8 i = 0; i < lines; i++) { - TInt16 x0 = *glyph++, y0 = *glyph++, x1 = *glyph++, y1 = *glyph++; - - gDisplay.renderBitmap->DrawLine( - ENull, - x + x0 * fscale, - y + y0 * fscale, - x + x1 * fscale, - y + y1 * fscale, - color - ); - } - } - return width * fscale; -} - -TInt8 Font::write(TInt16 x, TInt16 y, char c) { return write(SHMOO_COLOR, x, y, c); } - -TInt8 Font::print_string(TUint8 color, TInt16 x, TInt16 y, char *s) { - TInt8 xx = x; - while (char c = *s++) { - TInt8 width = Font::write(x, y, c); - x += width; - } - return x - xx; // width of string printed -} - -TInt8 Font::print_long(TUint8 color, TInt16 x, TInt16 y, TInt32 n, TInt8 base) { - // TODO: Fix me -- - char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte. - char *str = &buf[sizeof(buf) - 1]; - - *str = '\0'; - - // prevent crash if called with base == 1 - if (base < 2) - base = 10; - - do { - char c = n % base; - n /= base; - - *--str = c < 10 ? c + '0' : c + 'A' - 10; - } while (n); - - return print_string(color, x, y, str); -} - -#ifdef PRINTF_TFloat -TInt8 Font::print_float(TUint8 color, TInt16 x, TInt16 y, double number, - TInt8 digits) { - // TODO: Fix me -- - return 1; - TInt8 xx = x; - if (isnan(number)) { - x += write(x, y, 'n'); - x += write(x, y, 'a'); - x += write(x, y, 'n'); - return x; - } - if (isinf(number)) { - x += write(x, y, 'i'); - x += write(x, y, 'n'); - x += write(x, y, 'f'); - return x; - } - if (number > 4294967040.0 || number < -4294967040.0) { - x += write(x, y, 'o'); - x += write(x, y, 'v'); - x += write(x, y, 'f'); - return x; - } - - // Handle negative numbers - if (number < 0.0) { - x += write(x, y, '-'); - number = -number; - } - - // Round correctly so that print(1.999, 2) prints as "2.00" - double rounding = 0.5; - for (uint8_t i = 0; i < digits; ++i) - rounding /= 10.0; - - number += rounding; - - // Extract the integer part of the number and print it - unsigned long int_part = (unsigned long)number; - double remainder = number - (double)int_part; - x += print_long(color, x, y, int_part, 10); - - // Print the decimal point, but only if there are digits beyond - if (digits > 0) { - x += write(x, y, '.'); - } - - // Extract digits from the remainder one at a time - while (digits-- > 0) { - remainder *= 10.0; - unsigned int toPrint = (unsigned int)(remainder); - x += print_long(color, x, y, toPrint, 10); - remainder -= toPrint; - } - - return x - xx; -} -#endif - -TInt8 Font::printf(TUint8 color, TInt16 x, TInt16 y, const char *ifsh, ...) { - va_list ap; - TInt8 xx = x; - char c; - const char * p = reinterpret_cast(ifsh); - va_start(ap, ifsh); - - while ((c = *p++)) { - if (c == '%') { - c = *p++; - switch (c) { - case '\0': - va_end(ap); - return x - xx; -#ifdef PRINTF_TFloat - case '%': - x += Font::write(color, x, y, '%'); - break; - case 'f': - x += print_float(color, x, y, va_arg(ap, double)); - break; -#endif - case 'd': - x += print_long(color, x, y, (long)va_arg(ap, int)); - break; -#ifdef PRINTF_TFloat - case 'x': - x += print_long(color, x, y, (long)va_arg(ap, int) & 0xffff, 16); - break; - case 'l': - x += print_long(color, x, y, va_arg(ap, long)); - break; -#endif - default: - x += Font::write(color, x, y, c); - break; - } - } else { - x += Font::write(color, x, y, c); - } - } - va_end(ap); - return xx - x; -} - -TInt8 Font::printf(TInt16 x, TInt16 y, const char *ifsh, ...) { - va_list ap; - TInt8 xx = x; - char c; - const char * p = reinterpret_cast(ifsh); - va_start(ap, ifsh); - - while ((c = *p++)) { - if (c == '%') { - c = *p++; - switch (c) { - case '\0': - va_end(ap); - return x - xx; -#ifdef PRINTF_TFloat - case '%': - x += Font::write(SHMOO_COLOR, x, y, '%'); - break; - case 'f': - x += print_float(SHMOO_COLOR, x, y, va_arg(ap, double)); - break; -#endif - case 'd': - x += print_long(SHMOO_COLOR, x, y, (TInt32)va_arg(ap, TInt)); - break; -#ifdef PRINTF_TFloat - case 'x': - x += print_long(SHMOO_COLOR, x, y, (long)va_arg(ap, int) & 0xffff, 16); - break; - case 'l': - x += print_long(SHMOO_COLOR, x, y, va_arg(ap, long)); - break; -#endif - default: - x += Font::write(SHMOO_COLOR, x, y, c); - break; - } - } else { - x += Font::write(SHMOO_COLOR, x, y, c); - } - } - va_end(ap); - return xx - x; -} diff --git a/Evade2/src/Font.h b/Evade2/src/Font.h deleted file mode 100644 index 799c198..0000000 --- a/Evade2/src/Font.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef FONT_H -#define FONT_H - -#include "Game.h" - -// this doesn't seem right, but it will probably work -// as in, Font::fprint(fmt, args...) - -class Font { - public: - static TInt16 scale; // 8.8 fixed point - - public: - // these routine return the width of whatever is printed to the screen - static TInt8 write(TUint8 color, TInt16 x, TInt16 y, char c); - static TInt8 write(TInt16 x, TInt16 y, char c); - static TInt8 printf(TInt16 x, TInt16 y, const char* ifsh, ...); - static TInt8 printf(TUint8 color, TInt16 x, TInt16 y, const char* ifsh, ...); - -#ifdef ENABLE_ROTATING_TEXT - static TInt8 print_string_rotatedx(TUint8 color, TInt16 x, TInt16 y, TFloat angle, const char* ifsh); - static TInt8 print_string_rotatedx(TInt16 x, TInt16 y, TFloat angle, const char* ifsh); -#endif - static TInt8 print_string(TUint8 color, TInt16 x, TInt16 y, char* s); - static TInt8 print_long(TUint8 color, TInt16 x, TInt16 y, TInt32 n, TInt8 base = 10); - -#ifdef PRINTF_TFloat - static TInt8 print_float(TUint8 color, TInt16 x, TInt16 y, double number, TInt8 digits = 2); -#endif -}; - -#endif diff --git a/Evade2/src/Game.h b/Evade2/src/Game.h index 3fb09f5..0bbbc79 100644 --- a/Evade2/src/Game.h +++ b/Evade2/src/Game.h @@ -1,6 +1,8 @@ #ifndef MODITE_GAME_H #define MODITE_GAME_H +#include + #define WIDTH 640 #define HEIGHT 400 #define SCREEN_WIDTH 320 diff --git a/Evade2/src/common/GVectorFont.cpp b/Evade2/src/common/GVectorFont.cpp new file mode 100644 index 0000000..2ad3c33 --- /dev/null +++ b/Evade2/src/common/GVectorFont.cpp @@ -0,0 +1,365 @@ +#include "GVectorFont.h" + +#define DEBUGME + +/** + * Some of this code lifted from Arduino serial Print class and modified. + * See: https://github.com/arduino/Arduino/blob/master/hardware/arduino/avr/cores/arduino/Print.cpp + */ + +#include "charset.h" +#include + +static const TInt8 *const charset[] = { + ENull, // space + font_emark, +#ifdef FULL_CHARSET + font_dquote, +#else + ENull, +#endif +#ifdef FULL_CHARSET + font_pound, // # +#else + ENull, +#endif +#ifdef FULL_CHARSET + font_dollar, // $ +#else + ENull, +#endif +#ifdef FULL_CHARSET + font_percent, // % +#else + ENull, +#endif +#ifdef FULL_CHARSET + font_amp, // & +#else + ENull, +#endif +#ifdef FULL_CHARSET + font_squote, // ' +#else + ENull, +#endif +#ifdef FULL_CHARSET + font_lparen, // ( +#else + ENull, +#endif +#ifdef FULL_CHARSET + font_rparen, // ) +#else + ENull, +#endif +#ifdef FULL_CHARSET + font_asterisk, // * +#else + ENull, +#endif +#ifdef FULL_CHARSET + font_plus, +#else + ENull, +#endif +#ifdef FULL_CHARSET + font_comma, +#else + ENull, +#endif +#ifdef FULL_CHARSET + font_minus, +#else + ENull, +#endif + font_period, + font_fslash, + font_0, + font_1, + font_2, + font_3, + font_4, + font_5, + font_6, + font_7, + font_8, + font_9, + font_colon, +#ifdef full_charset + font_semicolon, +#else + ENull, +#endif +#ifdef full_charset + font_lt, // < +#else + ENull, +#endif +#ifdef full_charset + font_eq, // = +#else + ENull, +#endif +#ifdef full_charset + font_gt, // > +#else + ENull, +#endif +#ifdef full_charset + font_qmark, +#else + ENull, +#endif +#ifdef full_charset + font_at, // @ +#else + ENull, +#endif + font_a, + font_b, + font_c, + font_d, + font_e, + font_f, + font_g, + font_h, + font_i, + font_j, + font_k, + font_l, + font_m, + font_n, + font_o, + font_p, + font_q, + font_r, + font_s, + font_t, + font_u, + font_v, + font_w, + font_x, + font_y, + font_z, +#ifdef full_charset + font_lt, // [ +#else + ENull, +#endif +#ifdef full_charset + font_bslash, // '\' +#else + ENull, +#endif +#ifdef full_charset + font_gt, // ] +#else + ENull, +#endif +#ifdef full_charset + font_caret, // ^ +#else + ENull, +#endif +#ifdef full_charset + font_uscore, // _ +#else + ENull, +#endif + ENull, // `` +}; + +WORD Font::scale = 0x100; + +#ifdef ENABLE_ROTATING_TEXT +TInt Font::print_string_rotatedx(TInt8 x, TInt8 y, FLOAT theta, const char *s) { + theta = float(theta) * 3.1415926 / 180; + FLOAT cost = cos(theta), + sint = sin(theta); + PGM_P p = reinterpret_cast(ifsh); + + FLOAT fscale = FLOAT(scale >> 8) + FLOAT(scale & 0xff) / 256.0; + + const TInt8 size = 9; + + TInt8 xo = x; + while (char c = pgm_read_byte(p++)) { + PGM_P glyph = (PGM_P)pgm_read_word(&charset[toupper(c) - 32]); + if (glyph) { + TInt8 lines = pgm_read_byte(glyph++); + + for (TInt8 i = 0; i < lines; i++) { + FLOAT x0 = (TInt8)pgm_read_byte(glyph++) * fscale + x, + y0 = (TInt8)pgm_read_byte(glyph++) * fscale + y, + x1 = (TInt8)pgm_read_byte(glyph++) * fscale + x, + y1 = (TInt8)pgm_read_byte(glyph++) * fscale + y; + + Graphics::drawLine( + x0, + ((y0 - y) * sint + cost + y), + x1, + ((y1 - y) * sint + cost + y)); + } + x += size * fscale; + } + else { + x += 6 * fscale; + } + } + return x - xo; +} +#endif + +TInt8 Font::write(TInt8 x, TInt8 y, char c) { + PGM_P glyph; + const TInt8 width = 9; + + FLOAT fscale = FLOAT(scale >> 8) + FLOAT(scale & 0xff) / 256.0; + glyph = (PGM_P)pgm_read_word(&charset[toupper(c) - 32]); + if (glyph) { + TInt8 lines = pgm_read_byte(glyph++); + + for (TInt8 i = 0; i < lines; i++) { + TInt8 x0 = pgm_read_byte(glyph++), + y0 = pgm_read_byte(glyph++), + x1 = pgm_read_byte(glyph++), + y1 = pgm_read_byte(glyph++); + + Graphics::drawLine(x + x0 * fscale, y + y0 * fscale, x + x1 * fscale, y + y1 * fscale); + } + } + return width * fscale; +} + +TInt8 Font::print_string(TInt8 x, TInt8 y, char *s) { + TInt8 xx = x; + while (char c = *s++) { + TInt8 width = Font::write(x, y, c); + x += width; + } + return x - xx; // width of string printed +} + +TInt8 Font::print_long(TInt8 x, TInt8 y, LONG n, TInt8 base) { + char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte. + char *str = &buf[sizeof(buf) - 1]; + + *str = '\0'; + + // prevent crash if called with base == 1 + if (base < 2) + base = 10; + + do { + char c = n % base; + n /= base; + + *--str = c < 10 ? c + '0' : c + 'A' - 10; + } while (n); + + return print_string(x, y, str); +} + +#ifdef PRINTF_FLOAT +TInt8 Font::print_float(TInt8 x, TInt8 y, double number, TInt8 digits) { + TInt8 xx = x; + if (isnan(number)) { + x += write(x, y, 'n'); + x += write(x, y, 'a'); + x += write(x, y, 'n'); + return x; + } + if (isinf(number)) { + x += write(x, y, 'i'); + x += write(x, y, 'n'); + x += write(x, y, 'f'); + return x; + } + if (number > 4294967040.0 || number < -4294967040.0) { + x += write(x, y, 'o'); + x += write(x, y, 'v'); + x += write(x, y, 'f'); + return x; + } + + // Handle negative numbers + if (number < 0.0) { + x += write(x, y, '-'); + number = -number; + } + + // Round correctly so that print(1.999, 2) prints as "2.00" + double rounding = 0.5; + for (uint8_t i = 0; i < digits; ++i) + rounding /= 10.0; + + number += rounding; + + // Extract the integer part of the number and print it + unsigned long int_part = (unsigned long)number; + double remainder = number - (double)int_part; + x += print_long(x, y, int_part, 10); + + // Print the decimal point, but only if there are digits beyond + if (digits > 0) { + x += write(x, y, '.'); + } + + // Extract digits from the remainder one at a time + while (digits-- > 0) { + remainder *= 10.0; + unsigned int toPrint = (unsigned int)(remainder); + x += print_long(x, y, toPrint, 10); + remainder -= toPrint; + } + + return x - xx; +} +#endif + +TInt8 Font::_printf(TInt8 x, TInt8 y, const char *s, ...) { + va_list ap; + TInt8 xx = x; + char c; + PGM_P p = reinterpret_cast(ifsh); + va_start(ap, ifsh); + + while (c = pgm_read_byte(p++)) { + if (c == '%') { + c = pgm_read_byte(p++); + switch (c) { + case '\0': + va_end(ap); + return x - xx; +#ifdef PRINTF_FLOAT + case '%': + x += Font::write(x, y, '%'); + break; + case 'f': + x += print_float(x, y, va_arg(ap, double)); + break; +#endif + case 'd': + x += print_long(x, y, (unsigned long)va_arg(ap, int)); + break; +#ifdef PRINTF_FLOAT + case 'x': + x += print_long(x, y, (unsigned long)va_arg(ap, int) & 0xffff, 16); + break; + case 'l': + x += print_long(x, y, va_arg(ap, long)); + break; +#endif + default: + x += Font::write(x, y, c); + break; + } + } + else { + x += Font::write(x, y, c); + } + } + va_end(ap); + return xx - x; +} diff --git a/Evade2/src/common/GVectorFont.h b/Evade2/src/common/GVectorFont.h new file mode 100644 index 0000000..1b91032 --- /dev/null +++ b/Evade2/src/common/GVectorFont.h @@ -0,0 +1,22 @@ +#ifndef EVADE2_GVECTORFONT_H +#define EVADE2_GVECTORFONT_H + +#include "Game.h" + +class GVectorFontFont { +public: + TFloat scale; // 8.8 fixed point + +public: + // these routine return the width of whatever is printed to the screen + TInt8 write(TInt8 x, TInt8 y, char c); + TInt8 printf(TInt8 x, TInt8 y, const char *s, ...); +#ifdef ENABLE_ROTATING_TEXT + TInt8 print_string_rotatedx(TInt8 x, TInt8 y, FLOAT angle, const char *s); +#endif + TInt8 print_string(TInt8 x, TInt8 y, char *s); + TInt8 print_long(TInt8 x, TInt8 y, TLong n, TInt8 base = 10); + TInt8 print_float(TInt8 x, TInt8 y, TFLoat number, TInt8 digits = 2); +}; + +#endif diff --git a/Evade2/src/charset.h b/Evade2/src/common/charset.h similarity index 85% rename from Evade2/src/charset.h rename to Evade2/src/common/charset.h index 9bfb1b6..70dcec5 100644 --- a/Evade2/src/charset.h +++ b/Evade2/src/common/charset.h @@ -1,13 +1,11 @@ #ifndef CHARSET_H #define CHARSET_H -#define FULL_CHARSET // number of characters: 61 -#include "Game.h" +#include "Evade2.h" -// clang-format off -const TInt8 font_a[] = { +const PROGMEM BYTE font_a[] = { // 9, // width // 9, // height 5, // Number of rows of coords @@ -19,7 +17,7 @@ const TInt8 font_a[] = { -4, 0, 2, 0, }; -const TInt8 font_b[] = { +const PROGMEM BYTE font_b[] = { // 9, // width // 9, // height 10, // Number of rows of coords @@ -36,7 +34,7 @@ const TInt8 font_b[] = { -4, 3, -4, -4, }; -const TInt8 font_c[] = { +const PROGMEM BYTE font_c[] = { // 9, // width // 9, // height 7, // Number of rows of coords @@ -50,7 +48,7 @@ const TInt8 font_c[] = { -4, -3, -2, -5, }; -const TInt8 font_d[] = { +const PROGMEM BYTE font_d[] = { // 9, // width // 9, // height 6, // Number of rows of coords @@ -63,7 +61,7 @@ const TInt8 font_d[] = { -4, 3, -4, -5, }; -const TInt8 font_e[] = { +const PROGMEM BYTE font_e[] = { // 9, // width // 9, // height 4, // Number of rows of coords @@ -74,7 +72,7 @@ const TInt8 font_e[] = { -4, 3, 2, 3, }; -const TInt8 font_f[] = { +const PROGMEM BYTE font_f[] = { // 9, // width // 9, // height 3, // Number of rows of coords @@ -84,7 +82,7 @@ const TInt8 font_f[] = { -4, -1, -4, 3, }; -const TInt8 font_g[] = { +const PROGMEM BYTE font_g[] = { // 9, // width // 9, // height 9, // Number of rows of coords @@ -100,7 +98,7 @@ const TInt8 font_g[] = { 2, -1, 2, 2, }; -const TInt8 font_h[] = { +const PROGMEM BYTE font_h[] = { // 9, // width // 9, // height 4, // Number of rows of coords @@ -111,7 +109,7 @@ const TInt8 font_h[] = { 2, -5, 2, 3, }; -const TInt8 font_i[] = { +const PROGMEM BYTE font_i[] = { // 9, // width // 9, // height 3, // Number of rows of coords @@ -121,7 +119,7 @@ const TInt8 font_i[] = { -2, 3, 0, 3, }; -const TInt8 font_j[] = { +const PROGMEM BYTE font_j[] = { // 9, // width // 9, // height 5, // Number of rows of coords @@ -133,7 +131,7 @@ const TInt8 font_j[] = { -3, 1, -3, 0, }; -const TInt8 font_k[] = { +const PROGMEM BYTE font_k[] = { // 9, // width // 9, // height 5, // Number of rows of coords @@ -145,7 +143,7 @@ const TInt8 font_k[] = { 1, 3, -3, -1, }; -const TInt8 font_l[] = { +const PROGMEM BYTE font_l[] = { // 9, // width // 9, // height 3, // Number of rows of coords @@ -155,7 +153,7 @@ const TInt8 font_l[] = { -1, 3, 1, 1, }; -const TInt8 font_m[] = { +const PROGMEM BYTE font_m[] = { // 9, // width // 9, // height 4, // Number of rows of coords @@ -166,7 +164,7 @@ const TInt8 font_m[] = { 2, -5, 2, 3, }; -const TInt8 font_n[] = { +const PROGMEM BYTE font_n[] = { // 9, // width // 9, // height 3, // Number of rows of coords @@ -176,7 +174,7 @@ const TInt8 font_n[] = { 2, 3, 2, -5, }; -const TInt8 font_o[] = { +const PROGMEM BYTE font_o[] = { // 9, // width // 9, // height 7, // Number of rows of coords @@ -190,7 +188,7 @@ const TInt8 font_o[] = { -4, 1, -4, -3, }; -const TInt8 font_p[] = { +const PROGMEM BYTE font_p[] = { // 9, // width // 9, // height 6, // Number of rows of coords @@ -203,7 +201,7 @@ const TInt8 font_p[] = { -4, -4, -4, 3, }; -const TInt8 font_q[] = { +const PROGMEM BYTE font_q[] = { // 9, // width // 9, // height 8, // Number of rows of coords @@ -218,7 +216,7 @@ const TInt8 font_q[] = { 0, 1, 2, 3, }; -const TInt8 font_r[] = { +const PROGMEM BYTE font_r[] = { // 9, // width // 9, // height 7, // Number of rows of coords @@ -232,7 +230,7 @@ const TInt8 font_r[] = { -1, 0, 2, 3, }; -const TInt8 font_s[] = { +const PROGMEM BYTE font_s[] = { // 9, // width // 9, // height 7, // Number of rows of coords @@ -246,7 +244,7 @@ const TInt8 font_s[] = { 0, 3, -4, 3, }; -const TInt8 font_t[] = { +const PROGMEM BYTE font_t[] = { // 9, // width // 9, // height 2, // Number of rows of coords @@ -255,7 +253,7 @@ const TInt8 font_t[] = { -1, -2, -1, 3, }; -const TInt8 font_u[] = { +const PROGMEM BYTE font_u[] = { // 9, // width // 9, // height 5, // Number of rows of coords @@ -267,7 +265,7 @@ const TInt8 font_u[] = { 2, 2, 2, -5, }; -const TInt8 font_v[] = { +const PROGMEM BYTE font_v[] = { // 9, // width // 9, // height 4, // Number of rows of coords @@ -278,7 +276,7 @@ const TInt8 font_v[] = { 2, 0, 2, -5, }; -const TInt8 font_w[] = { +const PROGMEM BYTE font_w[] = { // 9, // width // 9, // height 4, // Number of rows of coords @@ -289,7 +287,7 @@ const TInt8 font_w[] = { 2, 3, 2, -5, }; -const TInt8 font_x[] = { +const PROGMEM BYTE font_x[] = { // 9, // width // 9, // height 6, // Number of rows of coords @@ -302,7 +300,7 @@ const TInt8 font_x[] = { -4, 2, -4, 3, }; -const TInt8 font_y[] = { +const PROGMEM BYTE font_y[] = { // 9, // width // 9, // height 3, // Number of rows of coords @@ -312,7 +310,7 @@ const TInt8 font_y[] = { -1, -1, -1, 3, }; -const TInt8 font_z[] = { +const PROGMEM BYTE font_z[] = { // 9, // width // 9, // height 4, // Number of rows of coords @@ -323,7 +321,7 @@ const TInt8 font_z[] = { -4, 3, 2, 3, }; -const TInt8 font_0[] = { +const PROGMEM BYTE font_0[] = { // 9, // width // 9, // height 9, // Number of rows of coords @@ -339,7 +337,7 @@ const TInt8 font_0[] = { -4, -3, -2, -5, }; -const TInt8 font_1[] = { +const PROGMEM BYTE font_1[] = { // 9, // width // 9, // height 2, // Number of rows of coords @@ -348,7 +346,7 @@ const TInt8 font_1[] = { 0, -5, 0, 3, }; -const TInt8 font_2[] = { +const PROGMEM BYTE font_2[] = { // 9, // width // 9, // height 10, // Number of rows of coords @@ -365,7 +363,7 @@ const TInt8 font_2[] = { -3, 3, 2, 3, }; -const TInt8 font_3[] = { +const PROGMEM BYTE font_3[] = { // 9, // width // 9, // height 10, // Number of rows of coords @@ -382,7 +380,7 @@ const TInt8 font_3[] = { 1, 3, -4, 3, }; -const TInt8 font_4[] = { +const PROGMEM BYTE font_4[] = { // 9, // width // 9, // height 4, // Number of rows of coords @@ -393,7 +391,7 @@ const TInt8 font_4[] = { 1, -5, 1, 3, }; -const TInt8 font_5[] = { +const PROGMEM BYTE font_5[] = { // 9, // width // 9, // height 10, // Number of rows of coords @@ -410,7 +408,7 @@ const TInt8 font_5[] = { -3, 3, -4, 2, }; -const TInt8 font_6[] = { +const PROGMEM BYTE font_6[] = { // 9, // width // 9, // height 11, // Number of rows of coords @@ -428,7 +426,7 @@ const TInt8 font_6[] = { -4, 0, -3, -1, }; -const TInt8 font_7[] = { +const PROGMEM BYTE font_7[] = { // 9, // width // 9, // height 3, // Number of rows of coords @@ -438,7 +436,7 @@ const TInt8 font_7[] = { 2, -4, 2, 3, }; -const TInt8 font_8[] = { +const PROGMEM BYTE font_8[] = { // 9, // width // 9, // height 15, // Number of rows of coords @@ -460,7 +458,7 @@ const TInt8 font_8[] = { -4, 0, -3, -1, }; -const TInt8 font_9[] = { +const PROGMEM BYTE font_9[] = { // 9, // width // 9, // height 11, // Number of rows of coords @@ -481,7 +479,7 @@ const TInt8 font_9[] = { #ifdef FULL_CHARSET -const TInt8 font_qmark[] = { +const PROGMEM BYTE font_qmark[] = { // 9, // width // 9, // height 8, // Number of rows of coords @@ -499,7 +497,7 @@ const TInt8 font_qmark[] = { -const TInt8 font_emark[] = { +const PROGMEM BYTE font_emark[] = { // 9, // width // 9, // height 2, // Number of rows of coords @@ -511,7 +509,7 @@ const TInt8 font_emark[] = { #ifdef FULL_CHARSET -const TInt8 font_comma[] = { +const PROGMEM BYTE font_comma[] = { // 9, // width // 9, // height 2, // Number of rows of coords @@ -521,7 +519,7 @@ const TInt8 font_comma[] = { }; #endif -const TInt8 font_period[] = { +const PROGMEM BYTE font_period[] = { // 9, // width // 9, // height 1, // Number of rows of coords @@ -530,7 +528,7 @@ const TInt8 font_period[] = { }; -const TInt8 font_colon[] = { +const PROGMEM BYTE font_colon[] = { // 9, // width // 9, // height 2, // Number of rows of coords @@ -540,7 +538,7 @@ const TInt8 font_colon[] = { }; #ifdef FULL_CHARSET -const TInt8 font_semicolon[] = { +const PROGMEM BYTE font_semicolon[] = { // 9, // width // 9, // height 3, // Number of rows of coords @@ -550,7 +548,7 @@ const TInt8 font_semicolon[] = { -1, 1, -2, 2, }; -const TInt8 font_plus[] = { +const PROGMEM BYTE font_plus[] = { // 9, // width // 9, // height 2, // Number of rows of coords @@ -559,7 +557,7 @@ const TInt8 font_plus[] = { -3, -1, 1, -1, }; -const TInt8 font_minus[] = { +const PROGMEM BYTE font_minus[] = { // 9, // width // 9, // height 1, // Number of rows of coords @@ -568,7 +566,7 @@ const TInt8 font_minus[] = { }; #endif -const TInt8 font_fslash[] = { +const PROGMEM BYTE font_fslash[] = { // 9, // width // 9, // height 1, // Number of rows of coords @@ -577,7 +575,7 @@ const TInt8 font_fslash[] = { }; #ifdef FULL_CHARSET -const TInt8 font_bslash[] = { +const PROGMEM BYTE font_bslash[] = { // 9, // width // 9, // height 1, // Number of rows of coords @@ -585,7 +583,7 @@ const TInt8 font_bslash[] = { -4, -4, 2, 2, }; -const TInt8 font_lt[] = { +const PROGMEM BYTE font_lt[] = { // 9, // width // 9, // height 2, // Number of rows of coords @@ -594,7 +592,7 @@ const TInt8 font_lt[] = { -4, -1, 0, 3, }; -const TInt8 font_gt[] = { +const PROGMEM BYTE font_gt[] = { // 9, // width // 9, // height 2, // Number of rows of coords @@ -606,7 +604,7 @@ const TInt8 font_gt[] = { #ifdef FULL_CHARSET -const TInt8 font_dquote[] = { +const PROGMEM BYTE font_dquote[] = { // 9, // width // 9, // height 2, // Number of rows of coords @@ -615,7 +613,7 @@ const TInt8 font_dquote[] = { 0, -5, 0, -3, }; -const TInt8 font_squote[] = { +const PROGMEM BYTE font_squote[] = { // 9, // width // 9, // height 1, // Number of rows of coords @@ -623,7 +621,7 @@ const TInt8 font_squote[] = { -1, -5, -1, -3, }; -const TInt8 font_lparen[] = { +const PROGMEM BYTE font_lparen[] = { // 9, // width // 9, // height 3, // Number of rows of coords @@ -633,7 +631,7 @@ const TInt8 font_lparen[] = { -4, 1, -2, 3, }; -const TInt8 font_rparen[] = { +const PROGMEM BYTE font_rparen[] = { // 9, // width // 9, // height 3, // Number of rows of coords @@ -643,7 +641,7 @@ const TInt8 font_rparen[] = { -2, 1, -4, 3, }; -const TInt8 font_eq[] = { +const PROGMEM BYTE font_eq[] = { // 9, // width // 9, // height 2, // Number of rows of coords @@ -652,7 +650,7 @@ const TInt8 font_eq[] = { -2, 0, 0, 0, }; -const TInt8 font_caret[] = { +const PROGMEM BYTE font_caret[] = { // 9, // width // 9, // height 2, // Number of rows of coords @@ -661,7 +659,7 @@ const TInt8 font_caret[] = { -1, -5, 1, -3, }; -const TInt8 font_uscore[] = { +const PROGMEM BYTE font_uscore[] = { // 9, // width // 9, // height 1, // Number of rows of coords @@ -669,7 +667,7 @@ const TInt8 font_uscore[] = { -3, 3, 1, 3, }; -const TInt8 font_at[] = { +const PROGMEM BYTE font_at[] = { // 9, // width // 9, // height 14, // Number of rows of coords @@ -690,7 +688,7 @@ const TInt8 font_at[] = { 0, -2, 0, 0, }; -const TInt8 font_pound[] = { +const PROGMEM BYTE font_pound[] = { // 9, // width // 9, // height 4, // Number of rows of coords @@ -701,7 +699,7 @@ const TInt8 font_pound[] = { -4, 0, 2, 0, }; -const TInt8 font_dollar[] = { +const PROGMEM BYTE font_dollar[] = { // 9, // width // 9, // height 13, // Number of rows of coords @@ -721,7 +719,7 @@ const TInt8 font_dollar[] = { -3, 2, -4, 1, }; -const TInt8 font_asterisk[] = { +const PROGMEM BYTE font_asterisk[] = { // 9, // width // 9, // height 3, // Number of rows of coords @@ -731,7 +729,7 @@ const TInt8 font_asterisk[] = { -1, -5, -1, -4, }; -const TInt8 font_percent[] = { +const PROGMEM BYTE font_percent[] = { // 9, // width // 9, // height 7, // Number of rows of coords @@ -745,7 +743,7 @@ const TInt8 font_percent[] = { 0, 2, 0, 0, }; -const TInt8 font_amp[] = { +const PROGMEM BYTE font_amp[] = { // 9, // width // 9, // height 11, // Number of rows of coords From 0894f091b2b7d63fd3c9ad0572e122e1afc9fc1f Mon Sep 17 00:00:00 2001 From: Michael Schwartz Date: Sun, 1 Nov 2020 13:32:44 -0800 Subject: [PATCH 2/6] player implemented, not tested --- Evade2/CMakeLists.txt | 1 + Evade2/src/Game.h | 10 +- Evade2/src/GameState/GPlayerProcess.cpp | 324 ++++++++++++++++++++++++ Evade2/src/GameState/GPlayerProcess.h | 39 +++ Evade2/src/common/GVectorFont.cpp | 103 ++++---- Evade2/src/common/GVectorFont.h | 14 +- Evade2/src/common/charset.h | 124 ++++----- 7 files changed, 497 insertions(+), 118 deletions(-) create mode 100644 Evade2/src/GameState/GPlayerProcess.cpp create mode 100644 Evade2/src/GameState/GPlayerProcess.h diff --git a/Evade2/CMakeLists.txt b/Evade2/CMakeLists.txt index 251b9eb..e18aa7b 100644 --- a/Evade2/CMakeLists.txt +++ b/Evade2/CMakeLists.txt @@ -27,6 +27,7 @@ INCLUDE(${CMAKE_CURRENT_SOURCE_DIR}/creative-engine/CreativeEngine.cmake) SET(EVADE2_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/src/resources + ${CMAKE_SOURCE_DIR}/src/common # ${CMAKE_SOURCE_DIR}/src/LoadGameState # ${CMAKE_SOURCE_DIR}/src/GameState # ${CMAKE_SOURCE_DIR}/src/GameState/environment diff --git a/Evade2/src/Game.h b/Evade2/src/Game.h index 0bbbc79..4e0d76d 100644 --- a/Evade2/src/Game.h +++ b/Evade2/src/Game.h @@ -10,6 +10,7 @@ #define SCREEN_DEPTH 8 const float CAMERA_VZ = 4; +const float DELTACONTROL = 11; #define FRAME_RATE_INFO 0 #undef FRAME_RATE_INFO @@ -49,6 +50,7 @@ const float CAMERA_VZ = 4; //const TUint16 FACTOR = FRAMES_PER_SECOND / 30; #include "GResources.h" +#include "common/GVectorFont.h" #include "GGame.h" //#include "common/GDialogWidget.h" //#include "common/GButtonWidget.h" @@ -80,10 +82,10 @@ const TUint16 CONTROL_JOYDOWN = JOYDOWN; const TUint16 CONTROL_JOYLEFT = JOYLEFT; const TUint16 CONTROL_JOYRIGHT = JOYRIGHT; const TUint16 CONTROL_FIRE = BUTTONA; -const TUint16 CONTROL_RUN = BUTTONB; -const TUint16 CONTROL_SPELL = BUTTONX; -const TUint16 CONTROL_INVENTORY = BUTTONR; -const TUint16 CONTROL_TARGET = BUTTONL; +const TUint16 CONTROL_BURST = BUTTONB; +/* const TUint16 CONTROL_SPELL = BUTTONX; */ +/* const TUint16 CONTROL_INVENTORY = BUTTONR; */ +/* const TUint16 CONTROL_TARGET = BUTTONL; */ const TUint16 CONTROL_DEBUG = BUTTON_SELECT; struct EnemyConfig { diff --git a/Evade2/src/GameState/GPlayerProcess.cpp b/Evade2/src/GameState/GPlayerProcess.cpp new file mode 100644 index 0000000..5f1f042 --- /dev/null +++ b/Evade2/src/GameState/GPlayerProcess.cpp @@ -0,0 +1,324 @@ +#include "GPlayerProcess.h" + +#define DEBUGME +//#undef DEBUGME + +#include "Game.h" +#include "GCamera.h" + +#include "img/hud_console_img.h" + +//TODO: Put in own files +const TUint8 crosshair_left_4x8[] = { + // width, height4, 8, + 0x81, 0x42, 0x24, 0x99 +}; + +// crosshair_right.png +// 4x8 +const TUint8 crosshair_right_4x8[] = { + // width, height 4, 8, + 0x99, 0x24, 0x42, 0x81 +}; + +#define MAX_POWER 100 +#define MAX_LIFE 100 + +GPlayerProcess::GPlayerProcess() { + GCamera::mVZ = CAMERA_VZ; + power = MAX_POWER; + shield = MAX_LIFE; + num_bullets = 0; + flags = 0; +} + +void GPlayerProcess::DrawPixel(TFloat x, TFloat y) { + gDisplay.renderBitmap->WritePixel(x, y, color); +} + +void GPlayerProcess::DrawLine(TFloat x1, TFloat y1, TFloat x2, TFloat y2) { + gDisplay.renderBitmap->DrawLine(gViewPort, x1, y1, x2, y2, color); +} + +void GPlayerProcess::DrawBitmap(TInt16 x, TInt16 y, const TUint8 *bitmap, TUint8 w, TUint8 h, TUint8 color) { + #if 0 + // no need to draw at all if we're offscreen + if (x + w < 0 || x > WIDTH - 1 || y + h < 0 || y > HEIGHT - 1) + return; + + return; + int yOffset = abs(y) % 8; + int sRow = y / 8; + if (y < 0) { + sRow--; + yOffset = 8 - yOffset; + } + int rows = h / 8; + if (h % 8 != 0) + rows++; + for (int a = 0; a < rows; a++) { + int bRow = sRow + a; + if (bRow > (HEIGHT / 8) - 1) + break; + if (bRow > -2) { + for (int iCol = 0; iCol < w; iCol++) { + if (iCol + x > (WIDTH - 1)) + break; + if (iCol + x >= 0) { + const TUint8 bmp_bits = pgm_read_byte(bitmap + (a * w) + iCol); + if (bRow >= 0) { + if (color == WHITE) + sBuffer[(bRow * WIDTH) + x + iCol] |= bmp_bits << yOffset; + else if (color == BLACK) + sBuffer[(bRow * WIDTH) + x + iCol] &= ~(bmp_bits << yOffset); + else + sBuffer[(bRow * WIDTH) + x + iCol] ^= bmp_bits << yOffset; + } + if (yOffset && bRow < (HEIGHT / 8) - 1 && bRow > -2) { + if (color == WHITE) + sBuffer[((bRow + 1) * WIDTH) + x + iCol] |= bmp_bits >> (8 - yOffset); + else if (color == BLACK) + sBuffer[((bRow + 1) * WIDTH) + x + iCol] &= ~(bmp_bits >> (8 - yOffset)); + else + sBuffer[((bRow + 1) * WIDTH) + x + iCol] ^= bmp_bits >> (8 - yOffset); + } + } + } + } + } + #endif +} + +void GPlayerProcess::hit(TInt8 amount) { + shield -= amount; + if (shield <= 0) { + // ProcessManager::birth(GameOver::entry); + } + else { + flags |= PLAYER_FLAG_HIT; + // Sound::play_sound(SFX_PLAYER_HIT_BY_ENEMY); + } +} + +void GPlayerProcess::recharge_shield() { + if (shield < MAX_LIFE) { + shield++; + } +} + +void GPlayerProcess::recharge_power() { + if (power < MAX_POWER) { + power++; + } +} + +TBool GPlayerProcess::RunBefore() { + if (gGame->GetState() == GAME_STATE_GAME) { + // if (game_mode != MODE_GAME) { + GCamera::mVX = GCamera::mVY = 0; + return ETrue; + } + + if (gControls.WasPressed(CONTROL_FIRE)) { + TInt8 deltaX = 0, + deltaY = 0; + + deltaX = gControls.IsPressed(CONTROL_JOYRIGHT) ? -12 : deltaX; + deltaX = gControls.IsPressed(CONTROL_JOYLEFT) ? 12 : deltaX; + + deltaY = gControls.IsPressed(CONTROL_JOYUP) ? -11 : deltaY; + deltaY = gControls.IsPressed(CONTROL_JOYDOWN) ? 13 : deltaY; + + // Bullet::fire(deltaX, deltaY, Player::flags & PLAYER_FLAG_ALT); + flags ^= PLAYER_FLAG_ALT; + } + + if (gControls.IsPressed(CONTROL_BURST)) { + if (power > 0) { + GCamera::mVZ = CAMERA_VZ * 2; + power--; + if (power < 0) { + power = 0; + } + } + else { + GCamera::mVZ = CAMERA_VZ; + } + } + else { + GCamera::mVZ = CAMERA_VZ; + power++; + if (power > MAX_POWER) { + power = MAX_POWER; + } + } + + if (gControls.IsPressed(CONTROL_JOYRIGHT)) { + GCamera::mVX = -DELTACONTROL; + } + else if (gControls.IsPressed(CONTROL_JOYLEFT)) { + GCamera::mVX = DELTACONTROL; + } + else { + GCamera::mVX = 0; + } + + if (gControls.IsPressed(CONTROL_JOYDOWN)) { + GCamera::mVY = DELTACONTROL; + } + else if (gControls.IsPressed(CONTROL_JOYUP)) { + GCamera::mVY = -DELTACONTROL; + } + else { + GCamera::mVY = 0; + } + return ETrue; +} + +/************************************************************************/ +/** HUD */ +/************************************************************************/ + +#ifdef ENABLE_HUD_MOVEMENTS + +// 13 == full. Anything less, and we draw "less meter" +static void drawMeter(TInt8 side, TInt8 value, TInt8 deltaXMeter, TInt8 deltaYMeter) { + + //start at X:14 + // Draw 2 lines, skip one line, iterate 13 total times + // if left, X:0, else X:128 + // Y Step is 3 + + // TODO: Tighten up! + TInt8 y = 45; + value /= 10; + if (side == 0) { // LEFT + for (TInt8 i = 0; i < 10; i++) { + if (i >= value) { + DrawPixel(1 + deltaXMeter, y + deltaYMeter); + DrawPixel(1 + deltaXMeter, y + 1 + deltaYMeter); + } + else { + DrawLine(1 + deltaXMeter, y + deltaYMeter, 3 + deltaXMeter, y + deltaYMeter); + DrawLine(1 + deltaXMeter, y + 1 + deltaYMeter, 4 + deltaXMeter, y + 1 + deltaYMeter); + } + y -= 3; + } + } + else { // RIGHT + for (TInt8 i = 0; i < 10; i++) { + if (i >= value) { + DrawPixel(126 + deltaXMeter, y + deltaYMeter); + DrawPixel(126 + deltaXMeter, y + 1 + deltaYMeter); + } + else { + DrawLine(124 + deltaXMeter, y + deltaYMeter, 126 + deltaXMeter, y + deltaYMeter); + DrawLine(123 + deltaXMeter, y + 1 + deltaYMeter, 126 + deltaXMeter, y + 1 + deltaYMeter); + } + y -= 3; + } + } +} + +#else + +// 13 == full. Anything less, and we draw "less meter" +void GPlayerProcess::drawMeter(TInt8 side, TInt8 value) { + + //start at X:14 + // Draw 2 lines, skip one line, iterate 13 total times + // if left, X:0, else X:128 + // Y Step is 3 + + // TODO: Tighten up! + TInt8 y = 45; + value /= 10; + if (side == 0) { // LEFT + for (TInt8 i = 0; i < 10; i++) { + if (i >= value) { + DrawPixel(0, y); + DrawPixel(0, y + 1); + } + else { + DrawLine(0, y, 2, y); + DrawLine(0, y + 1, 3, y + 1); + } + y -= 3; + } + } + else { // RIGHT + for (TInt8 i = 0; i < 10; i++) { + if (i >= value) { + DrawPixel(127, y); + DrawPixel(127, y + 1); + } + else { + DrawLine(126, y, 128, y); + DrawLine(125, y + 1, 128, y + 1); + } + y -= 3; + } + } +} + +#endif // #if ENABLE_HUD_MOVEMENTS + +TBool GPlayerProcess::RunAfter() { + // TODO: swap background black -> white -> black + // arduboy.invert(flags & PLAYER_FLAG_HIT); + flags &= ~PLAYER_FLAG_HIT; + +#ifdef ENABLE_HUD_MOVEMENTS + TInt8 consoleX = 40, + consoleY = 58, + deltaXMeter = 0, + deltaYMeter = 0, + deltaXCrossHairs = 0, + deltaYCrossHairs = 0; + + // Font::scale = .6 * 256; + // Font::printf(5,5,"D %d", Game::difficulty); + // Font::printf(5,12,"W %d", Game::wave); + // Font::scale = 256; + if (game_mode == MODE_GAME) { + + if (gControls.IsPressed(JOYSTICK_RIGHT)) { + consoleX = 38; + deltaXMeter = -1; + deltaXCrossHairs = 4; + } + else if (gControls.IsPressed(JOYSTICK_LEFT)) { + consoleX = 42; + deltaXMeter = 1; + deltaXCrossHairs = -4; + } + + if (gControls.IsPressed(JOYSTICK_UP)) { + consoleY = 56; + deltaYMeter = -1; + deltaYCrossHairs = 4; + } + else if (gControls.IsPressed(JOYSTICK_DOWN)) { + consoleY = 60; + deltaYMeter = 1; + deltaYCrossHairs = -4; + } + } + + DrawBitmap(consoleX, consoleY, hud_console_img, 0x30, 0x08); + // // DrawLine(64, 0, 64, 64); // used to measure the center of the screen. + + DrawBitmap(53 + deltaXCrossHairs, 30 + deltaYCrossHairs, crosshair_left_4x8, 4, 8); + DrawBitmap(72 + deltaXCrossHairs, 30 + deltaYCrossHairs, crosshair_right_4x8, 4, 8); + + drawMeter(0, shield, deltaXMeter, deltaYMeter); + drawMeter(1, power, deltaXMeter, deltaYMeter); + +#else + DrawBitmap(40, 58, hud_console_img, 0x30, 0x08); + + drawMeter(0, shield); + drawMeter(1, power); +#endif + return ETrue; +} diff --git a/Evade2/src/GameState/GPlayerProcess.h b/Evade2/src/GameState/GPlayerProcess.h new file mode 100644 index 0000000..e7581de --- /dev/null +++ b/Evade2/src/GameState/GPlayerProcess.h @@ -0,0 +1,39 @@ +#ifndef EVADE2_GPLAYERPROCESS_H +#define EVADE2_GPLAYERPROCESS_H + +// player hit by enemy bullet +#define PLAYER_FLAG_HIT (1 << 0) +// which gun (left/right) to fire from +#define PLAYER_FLAG_ALT (1 << 1) + +#include "Game.h" +#include + +class GPlayerProcess : public BProcess { +public: + GPlayerProcess(); + +public: + TInt8 power; + TInt8 shield; + TInt8 num_bullets; + TUint8 flags; + TUint8 color; + +public: + void recharge_shield(); + void recharge_power(); + + void hit(TInt8 amount); + void DrawPixel(TFloat x, TFloat y); + void DrawLine(TFloat x1, TFloat y1, TFloat x2, TFloat y2); + +protected: + void drawMeter(TInt8 side, TInt8 value); + void DrawBitmap(TInt16 x, TInt16 y, const TUint8 *bitmap, TUint8 w, TUint8 h, TUint8 color = COLOR_WHITE); + +public: + TBool RunBefore(); + TBool RunAfter(); +}; +#endif diff --git a/Evade2/src/common/GVectorFont.cpp b/Evade2/src/common/GVectorFont.cpp index 2ad3c33..502a98e 100644 --- a/Evade2/src/common/GVectorFont.cpp +++ b/Evade2/src/common/GVectorFont.cpp @@ -10,7 +10,7 @@ #include "charset.h" #include -static const TInt8 *const charset[] = { +const TInt8 *charset[] = { ENull, // space font_emark, #ifdef FULL_CHARSET @@ -170,36 +170,41 @@ static const TInt8 *const charset[] = { ENull, // `` }; -WORD Font::scale = 0x100; +GVectorFont::GVectorFont() { + scale = 0x100; + color = COLOR_TEXT; +} #ifdef ENABLE_ROTATING_TEXT -TInt Font::print_string_rotatedx(TInt8 x, TInt8 y, FLOAT theta, const char *s) { +TInt8 GVectorFont::print_string_rotatedx(TInt8 x, TInt8 y, TFloat theta, const char *s) { theta = float(theta) * 3.1415926 / 180; - FLOAT cost = cos(theta), - sint = sin(theta); - PGM_P p = reinterpret_cast(ifsh); + TFloat cost = cos(theta), + sint = sin(theta); + const char *p = s; - FLOAT fscale = FLOAT(scale >> 8) + FLOAT(scale & 0xff) / 256.0; + TFloat fscale = TFloat(scale >> 8) + TFloat(scale & 0xff) / 256.0; const TInt8 size = 9; TInt8 xo = x; - while (char c = pgm_read_byte(p++)) { - PGM_P glyph = (PGM_P)pgm_read_word(&charset[toupper(c) - 32]); + while (char c = *p++) { + const TInt8 *glyph = charset[toupper(c) - 32]; if (glyph) { - TInt8 lines = pgm_read_byte(glyph++); + TInt8 lines = *glyph++; for (TInt8 i = 0; i < lines; i++) { - FLOAT x0 = (TInt8)pgm_read_byte(glyph++) * fscale + x, - y0 = (TInt8)pgm_read_byte(glyph++) * fscale + y, - x1 = (TInt8)pgm_read_byte(glyph++) * fscale + x, - y1 = (TInt8)pgm_read_byte(glyph++) * fscale + y; - - Graphics::drawLine( - x0, - ((y0 - y) * sint + cost + y), - x1, - ((y1 - y) * sint + cost + y)); + TFloat x0 = (TInt8)*glyph++ * fscale + x, + y0 = (TInt8)*glyph++ * fscale + y, + x1 = (TInt8)*glyph++ * fscale + x, + y1 = (TInt8)*glyph++ * fscale + y; + + gDisplay.renderBitmap->DrawLine( + gViewPort, + x0, + ((y0 - y) * sint + cost + y), + x1, + ((y1 - y) * sint + cost + y), + color); } x += size * fscale; } @@ -211,38 +216,42 @@ TInt Font::print_string_rotatedx(TInt8 x, TInt8 y, FLOAT theta, const char *s) { } #endif -TInt8 Font::write(TInt8 x, TInt8 y, char c) { - PGM_P glyph; +TInt8 GVectorFont::write(TInt8 x, TInt8 y, char c) { + const TInt8 *glyph; const TInt8 width = 9; - FLOAT fscale = FLOAT(scale >> 8) + FLOAT(scale & 0xff) / 256.0; - glyph = (PGM_P)pgm_read_word(&charset[toupper(c) - 32]); + TFloat fscale = TFloat(scale >> 8) + TFloat(scale & 0xff) / 256.0; + glyph = charset[toupper(c) - 32]; if (glyph) { - TInt8 lines = pgm_read_byte(glyph++); + TInt8 lines = *glyph++; for (TInt8 i = 0; i < lines; i++) { - TInt8 x0 = pgm_read_byte(glyph++), - y0 = pgm_read_byte(glyph++), - x1 = pgm_read_byte(glyph++), - y1 = pgm_read_byte(glyph++); - - Graphics::drawLine(x + x0 * fscale, y + y0 * fscale, x + x1 * fscale, y + y1 * fscale); + TInt8 x0 = *glyph++, + y0 = *glyph++, + x1 = *glyph++, + y1 = *glyph++; + + gDisplay.renderBitmap->DrawLine( + gViewPort, + x + x0 * fscale, y + y0 * fscale, + x + x1 * fscale, y + y1 * fscale, + color); } } return width * fscale; } -TInt8 Font::print_string(TInt8 x, TInt8 y, char *s) { +TInt8 GVectorFont::print_string(TInt8 x, TInt8 y, char *s) { TInt8 xx = x; while (char c = *s++) { - TInt8 width = Font::write(x, y, c); + TInt8 width = write(x, y, c); x += width; } return x - xx; // width of string printed } -TInt8 Font::print_long(TInt8 x, TInt8 y, LONG n, TInt8 base) { - char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte. +TInt8 GVectorFont::print_long(TInt8 x, TInt8 y, TInt64 n, TInt8 base) { + char buf[8 * sizeof(TInt64) + 1]; // Assumes 8-bit chars plus zero byte. char *str = &buf[sizeof(buf) - 1]; *str = '\0'; @@ -261,8 +270,8 @@ TInt8 Font::print_long(TInt8 x, TInt8 y, LONG n, TInt8 base) { return print_string(x, y, str); } -#ifdef PRINTF_FLOAT -TInt8 Font::print_float(TInt8 x, TInt8 y, double number, TInt8 digits) { +#ifdef PRINTF_TFloat +TInt8 GVectorFont::print_float(TInt8 x, TInt8 y, double number, TInt8 digits) { TInt8 xx = x; if (isnan(number)) { x += write(x, y, 'n'); @@ -318,23 +327,23 @@ TInt8 Font::print_float(TInt8 x, TInt8 y, double number, TInt8 digits) { } #endif -TInt8 Font::_printf(TInt8 x, TInt8 y, const char *s, ...) { +TInt8 GVectorFont::printf(TInt8 x, TInt8 y, const char *s, ...) { va_list ap; TInt8 xx = x; char c; - PGM_P p = reinterpret_cast(ifsh); - va_start(ap, ifsh); + const char *p = s; + va_start(ap, s); - while (c = pgm_read_byte(p++)) { + while ((c = *p++)) { if (c == '%') { - c = pgm_read_byte(p++); + c = *p++; switch (c) { case '\0': va_end(ap); return x - xx; -#ifdef PRINTF_FLOAT +#ifdef PRINTF_TFloat case '%': - x += Font::write(x, y, '%'); + x += write(x, y, '%'); break; case 'f': x += print_float(x, y, va_arg(ap, double)); @@ -343,7 +352,7 @@ TInt8 Font::_printf(TInt8 x, TInt8 y, const char *s, ...) { case 'd': x += print_long(x, y, (unsigned long)va_arg(ap, int)); break; -#ifdef PRINTF_FLOAT +#ifdef PRINTF_TFloat case 'x': x += print_long(x, y, (unsigned long)va_arg(ap, int) & 0xffff, 16); break; @@ -352,12 +361,12 @@ TInt8 Font::_printf(TInt8 x, TInt8 y, const char *s, ...) { break; #endif default: - x += Font::write(x, y, c); + x += write(x, y, c); break; } } else { - x += Font::write(x, y, c); + x += write(x, y, c); } } va_end(ap); diff --git a/Evade2/src/common/GVectorFont.h b/Evade2/src/common/GVectorFont.h index 1b91032..8153289 100644 --- a/Evade2/src/common/GVectorFont.h +++ b/Evade2/src/common/GVectorFont.h @@ -3,20 +3,24 @@ #include "Game.h" -class GVectorFontFont { +class GVectorFont{ public: - TFloat scale; // 8.8 fixed point + GVectorFont(); + +public: + TUint16 scale; // 8.8 fixed point + TUint8 color; // color to render text in public: // these routine return the width of whatever is printed to the screen TInt8 write(TInt8 x, TInt8 y, char c); TInt8 printf(TInt8 x, TInt8 y, const char *s, ...); #ifdef ENABLE_ROTATING_TEXT - TInt8 print_string_rotatedx(TInt8 x, TInt8 y, FLOAT angle, const char *s); + TInt8 print_string_rotatedx(TInt8 x, TInt8 y, TFloat angle, const char *s); #endif TInt8 print_string(TInt8 x, TInt8 y, char *s); - TInt8 print_long(TInt8 x, TInt8 y, TLong n, TInt8 base = 10); - TInt8 print_float(TInt8 x, TInt8 y, TFLoat number, TInt8 digits = 2); + TInt8 print_long(TInt8 x, TInt8 y, TInt64 n, TInt8 base = 10); + TInt8 print_float(TInt8 x, TInt8 y, TFloat number, TInt8 digits = 2); }; #endif diff --git a/Evade2/src/common/charset.h b/Evade2/src/common/charset.h index 70dcec5..56a1ad4 100644 --- a/Evade2/src/common/charset.h +++ b/Evade2/src/common/charset.h @@ -3,9 +3,9 @@ // number of characters: 61 -#include "Evade2.h" +/* #include "Evade2.h" */ -const PROGMEM BYTE font_a[] = { +const TInt8 font_a[] = { // 9, // width // 9, // height 5, // Number of rows of coords @@ -17,7 +17,7 @@ const PROGMEM BYTE font_a[] = { -4, 0, 2, 0, }; -const PROGMEM BYTE font_b[] = { +const TInt8 font_b[] = { // 9, // width // 9, // height 10, // Number of rows of coords @@ -34,7 +34,7 @@ const PROGMEM BYTE font_b[] = { -4, 3, -4, -4, }; -const PROGMEM BYTE font_c[] = { +const TInt8 font_c[] = { // 9, // width // 9, // height 7, // Number of rows of coords @@ -48,7 +48,7 @@ const PROGMEM BYTE font_c[] = { -4, -3, -2, -5, }; -const PROGMEM BYTE font_d[] = { +const TInt8 font_d[] = { // 9, // width // 9, // height 6, // Number of rows of coords @@ -61,7 +61,7 @@ const PROGMEM BYTE font_d[] = { -4, 3, -4, -5, }; -const PROGMEM BYTE font_e[] = { +const TInt8 font_e[] = { // 9, // width // 9, // height 4, // Number of rows of coords @@ -72,7 +72,7 @@ const PROGMEM BYTE font_e[] = { -4, 3, 2, 3, }; -const PROGMEM BYTE font_f[] = { +const TInt8 font_f[] = { // 9, // width // 9, // height 3, // Number of rows of coords @@ -82,7 +82,7 @@ const PROGMEM BYTE font_f[] = { -4, -1, -4, 3, }; -const PROGMEM BYTE font_g[] = { +const TInt8 font_g[] = { // 9, // width // 9, // height 9, // Number of rows of coords @@ -98,7 +98,7 @@ const PROGMEM BYTE font_g[] = { 2, -1, 2, 2, }; -const PROGMEM BYTE font_h[] = { +const TInt8 font_h[] = { // 9, // width // 9, // height 4, // Number of rows of coords @@ -109,7 +109,7 @@ const PROGMEM BYTE font_h[] = { 2, -5, 2, 3, }; -const PROGMEM BYTE font_i[] = { +const TInt8 font_i[] = { // 9, // width // 9, // height 3, // Number of rows of coords @@ -119,7 +119,7 @@ const PROGMEM BYTE font_i[] = { -2, 3, 0, 3, }; -const PROGMEM BYTE font_j[] = { +const TInt8 font_j[] = { // 9, // width // 9, // height 5, // Number of rows of coords @@ -131,7 +131,7 @@ const PROGMEM BYTE font_j[] = { -3, 1, -3, 0, }; -const PROGMEM BYTE font_k[] = { +const TInt8 font_k[] = { // 9, // width // 9, // height 5, // Number of rows of coords @@ -143,7 +143,7 @@ const PROGMEM BYTE font_k[] = { 1, 3, -3, -1, }; -const PROGMEM BYTE font_l[] = { +const TInt8 font_l[] = { // 9, // width // 9, // height 3, // Number of rows of coords @@ -153,7 +153,7 @@ const PROGMEM BYTE font_l[] = { -1, 3, 1, 1, }; -const PROGMEM BYTE font_m[] = { +const TInt8 font_m[] = { // 9, // width // 9, // height 4, // Number of rows of coords @@ -164,7 +164,7 @@ const PROGMEM BYTE font_m[] = { 2, -5, 2, 3, }; -const PROGMEM BYTE font_n[] = { +const TInt8 font_n[] = { // 9, // width // 9, // height 3, // Number of rows of coords @@ -174,7 +174,7 @@ const PROGMEM BYTE font_n[] = { 2, 3, 2, -5, }; -const PROGMEM BYTE font_o[] = { +const TInt8 font_o[] = { // 9, // width // 9, // height 7, // Number of rows of coords @@ -188,7 +188,7 @@ const PROGMEM BYTE font_o[] = { -4, 1, -4, -3, }; -const PROGMEM BYTE font_p[] = { +const TInt8 font_p[] = { // 9, // width // 9, // height 6, // Number of rows of coords @@ -201,7 +201,7 @@ const PROGMEM BYTE font_p[] = { -4, -4, -4, 3, }; -const PROGMEM BYTE font_q[] = { +const TInt8 font_q[] = { // 9, // width // 9, // height 8, // Number of rows of coords @@ -216,7 +216,7 @@ const PROGMEM BYTE font_q[] = { 0, 1, 2, 3, }; -const PROGMEM BYTE font_r[] = { +const TInt8 font_r[] = { // 9, // width // 9, // height 7, // Number of rows of coords @@ -230,7 +230,7 @@ const PROGMEM BYTE font_r[] = { -1, 0, 2, 3, }; -const PROGMEM BYTE font_s[] = { +const TInt8 font_s[] = { // 9, // width // 9, // height 7, // Number of rows of coords @@ -244,7 +244,7 @@ const PROGMEM BYTE font_s[] = { 0, 3, -4, 3, }; -const PROGMEM BYTE font_t[] = { +const TInt8 font_t[] = { // 9, // width // 9, // height 2, // Number of rows of coords @@ -253,7 +253,7 @@ const PROGMEM BYTE font_t[] = { -1, -2, -1, 3, }; -const PROGMEM BYTE font_u[] = { +const TInt8 font_u[] = { // 9, // width // 9, // height 5, // Number of rows of coords @@ -265,7 +265,7 @@ const PROGMEM BYTE font_u[] = { 2, 2, 2, -5, }; -const PROGMEM BYTE font_v[] = { +const TInt8 font_v[] = { // 9, // width // 9, // height 4, // Number of rows of coords @@ -276,7 +276,7 @@ const PROGMEM BYTE font_v[] = { 2, 0, 2, -5, }; -const PROGMEM BYTE font_w[] = { +const TInt8 font_w[] = { // 9, // width // 9, // height 4, // Number of rows of coords @@ -287,7 +287,7 @@ const PROGMEM BYTE font_w[] = { 2, 3, 2, -5, }; -const PROGMEM BYTE font_x[] = { +const TInt8 font_x[] = { // 9, // width // 9, // height 6, // Number of rows of coords @@ -300,7 +300,7 @@ const PROGMEM BYTE font_x[] = { -4, 2, -4, 3, }; -const PROGMEM BYTE font_y[] = { +const TInt8 font_y[] = { // 9, // width // 9, // height 3, // Number of rows of coords @@ -310,7 +310,7 @@ const PROGMEM BYTE font_y[] = { -1, -1, -1, 3, }; -const PROGMEM BYTE font_z[] = { +const TInt8 font_z[] = { // 9, // width // 9, // height 4, // Number of rows of coords @@ -321,7 +321,7 @@ const PROGMEM BYTE font_z[] = { -4, 3, 2, 3, }; -const PROGMEM BYTE font_0[] = { +const TInt8 font_0[] = { // 9, // width // 9, // height 9, // Number of rows of coords @@ -337,7 +337,7 @@ const PROGMEM BYTE font_0[] = { -4, -3, -2, -5, }; -const PROGMEM BYTE font_1[] = { +const TInt8 font_1[] = { // 9, // width // 9, // height 2, // Number of rows of coords @@ -346,7 +346,7 @@ const PROGMEM BYTE font_1[] = { 0, -5, 0, 3, }; -const PROGMEM BYTE font_2[] = { +const TInt8 font_2[] = { // 9, // width // 9, // height 10, // Number of rows of coords @@ -363,7 +363,7 @@ const PROGMEM BYTE font_2[] = { -3, 3, 2, 3, }; -const PROGMEM BYTE font_3[] = { +const TInt8 font_3[] = { // 9, // width // 9, // height 10, // Number of rows of coords @@ -380,7 +380,7 @@ const PROGMEM BYTE font_3[] = { 1, 3, -4, 3, }; -const PROGMEM BYTE font_4[] = { +const TInt8 font_4[] = { // 9, // width // 9, // height 4, // Number of rows of coords @@ -391,7 +391,7 @@ const PROGMEM BYTE font_4[] = { 1, -5, 1, 3, }; -const PROGMEM BYTE font_5[] = { +const TInt8 font_5[] = { // 9, // width // 9, // height 10, // Number of rows of coords @@ -408,7 +408,7 @@ const PROGMEM BYTE font_5[] = { -3, 3, -4, 2, }; -const PROGMEM BYTE font_6[] = { +const TInt8 font_6[] = { // 9, // width // 9, // height 11, // Number of rows of coords @@ -426,7 +426,7 @@ const PROGMEM BYTE font_6[] = { -4, 0, -3, -1, }; -const PROGMEM BYTE font_7[] = { +const TInt8 font_7[] = { // 9, // width // 9, // height 3, // Number of rows of coords @@ -436,7 +436,7 @@ const PROGMEM BYTE font_7[] = { 2, -4, 2, 3, }; -const PROGMEM BYTE font_8[] = { +const TInt8 font_8[] = { // 9, // width // 9, // height 15, // Number of rows of coords @@ -458,7 +458,7 @@ const PROGMEM BYTE font_8[] = { -4, 0, -3, -1, }; -const PROGMEM BYTE font_9[] = { +const TInt8 font_9[] = { // 9, // width // 9, // height 11, // Number of rows of coords @@ -479,7 +479,7 @@ const PROGMEM BYTE font_9[] = { #ifdef FULL_CHARSET -const PROGMEM BYTE font_qmark[] = { +const TInt8 font_qmark[] = { // 9, // width // 9, // height 8, // Number of rows of coords @@ -497,7 +497,7 @@ const PROGMEM BYTE font_qmark[] = { -const PROGMEM BYTE font_emark[] = { +const TInt8 font_emark[] = { // 9, // width // 9, // height 2, // Number of rows of coords @@ -509,7 +509,7 @@ const PROGMEM BYTE font_emark[] = { #ifdef FULL_CHARSET -const PROGMEM BYTE font_comma[] = { +const TInt8 font_comma[] = { // 9, // width // 9, // height 2, // Number of rows of coords @@ -519,7 +519,7 @@ const PROGMEM BYTE font_comma[] = { }; #endif -const PROGMEM BYTE font_period[] = { +const TInt8 font_period[] = { // 9, // width // 9, // height 1, // Number of rows of coords @@ -528,7 +528,7 @@ const PROGMEM BYTE font_period[] = { }; -const PROGMEM BYTE font_colon[] = { +const TInt8 font_colon[] = { // 9, // width // 9, // height 2, // Number of rows of coords @@ -538,7 +538,7 @@ const PROGMEM BYTE font_colon[] = { }; #ifdef FULL_CHARSET -const PROGMEM BYTE font_semicolon[] = { +const TInt8 font_semicolon[] = { // 9, // width // 9, // height 3, // Number of rows of coords @@ -548,7 +548,7 @@ const PROGMEM BYTE font_semicolon[] = { -1, 1, -2, 2, }; -const PROGMEM BYTE font_plus[] = { +const TInt8 font_plus[] = { // 9, // width // 9, // height 2, // Number of rows of coords @@ -557,7 +557,7 @@ const PROGMEM BYTE font_plus[] = { -3, -1, 1, -1, }; -const PROGMEM BYTE font_minus[] = { +const TInt8 font_minus[] = { // 9, // width // 9, // height 1, // Number of rows of coords @@ -566,7 +566,7 @@ const PROGMEM BYTE font_minus[] = { }; #endif -const PROGMEM BYTE font_fslash[] = { +const TInt8 font_fslash[] = { // 9, // width // 9, // height 1, // Number of rows of coords @@ -575,7 +575,7 @@ const PROGMEM BYTE font_fslash[] = { }; #ifdef FULL_CHARSET -const PROGMEM BYTE font_bslash[] = { +const TInt8 font_bslash[] = { // 9, // width // 9, // height 1, // Number of rows of coords @@ -583,7 +583,7 @@ const PROGMEM BYTE font_bslash[] = { -4, -4, 2, 2, }; -const PROGMEM BYTE font_lt[] = { +const TInt8 font_lt[] = { // 9, // width // 9, // height 2, // Number of rows of coords @@ -592,7 +592,7 @@ const PROGMEM BYTE font_lt[] = { -4, -1, 0, 3, }; -const PROGMEM BYTE font_gt[] = { +const TInt8 font_gt[] = { // 9, // width // 9, // height 2, // Number of rows of coords @@ -604,7 +604,7 @@ const PROGMEM BYTE font_gt[] = { #ifdef FULL_CHARSET -const PROGMEM BYTE font_dquote[] = { +const TInt8 font_dquote[] = { // 9, // width // 9, // height 2, // Number of rows of coords @@ -613,7 +613,7 @@ const PROGMEM BYTE font_dquote[] = { 0, -5, 0, -3, }; -const PROGMEM BYTE font_squote[] = { +const TInt8 font_squote[] = { // 9, // width // 9, // height 1, // Number of rows of coords @@ -621,7 +621,7 @@ const PROGMEM BYTE font_squote[] = { -1, -5, -1, -3, }; -const PROGMEM BYTE font_lparen[] = { +const TInt8 font_lparen[] = { // 9, // width // 9, // height 3, // Number of rows of coords @@ -631,7 +631,7 @@ const PROGMEM BYTE font_lparen[] = { -4, 1, -2, 3, }; -const PROGMEM BYTE font_rparen[] = { +const TInt8 font_rparen[] = { // 9, // width // 9, // height 3, // Number of rows of coords @@ -641,7 +641,7 @@ const PROGMEM BYTE font_rparen[] = { -2, 1, -4, 3, }; -const PROGMEM BYTE font_eq[] = { +const TInt8 font_eq[] = { // 9, // width // 9, // height 2, // Number of rows of coords @@ -650,7 +650,7 @@ const PROGMEM BYTE font_eq[] = { -2, 0, 0, 0, }; -const PROGMEM BYTE font_caret[] = { +const TInt8 font_caret[] = { // 9, // width // 9, // height 2, // Number of rows of coords @@ -659,7 +659,7 @@ const PROGMEM BYTE font_caret[] = { -1, -5, 1, -3, }; -const PROGMEM BYTE font_uscore[] = { +const TInt8 font_uscore[] = { // 9, // width // 9, // height 1, // Number of rows of coords @@ -667,7 +667,7 @@ const PROGMEM BYTE font_uscore[] = { -3, 3, 1, 3, }; -const PROGMEM BYTE font_at[] = { +const TInt8 font_at[] = { // 9, // width // 9, // height 14, // Number of rows of coords @@ -688,7 +688,7 @@ const PROGMEM BYTE font_at[] = { 0, -2, 0, 0, }; -const PROGMEM BYTE font_pound[] = { +const TInt8 font_pound[] = { // 9, // width // 9, // height 4, // Number of rows of coords @@ -699,7 +699,7 @@ const PROGMEM BYTE font_pound[] = { -4, 0, 2, 0, }; -const PROGMEM BYTE font_dollar[] = { +const TInt8 font_dollar[] = { // 9, // width // 9, // height 13, // Number of rows of coords @@ -719,7 +719,7 @@ const PROGMEM BYTE font_dollar[] = { -3, 2, -4, 1, }; -const PROGMEM BYTE font_asterisk[] = { +const TInt8 font_asterisk[] = { // 9, // width // 9, // height 3, // Number of rows of coords @@ -729,7 +729,7 @@ const PROGMEM BYTE font_asterisk[] = { -1, -5, -1, -4, }; -const PROGMEM BYTE font_percent[] = { +const TInt8 font_percent[] = { // 9, // width // 9, // height 7, // Number of rows of coords @@ -743,7 +743,7 @@ const PROGMEM BYTE font_percent[] = { 0, 2, 0, 0, }; -const PROGMEM BYTE font_amp[] = { +const TInt8 font_amp[] = { // 9, // width // 9, // height 11, // Number of rows of coords From e92a9dff8fa4399edb077f06530b98887d69cb53 Mon Sep 17 00:00:00 2001 From: Michael Schwartz Date: Mon, 2 Nov 2020 11:21:13 -0800 Subject: [PATCH 3/6] wip enemies fly, fire, player flies, fires, no collisions, scores, rest of stuff around the game --- Evade2/CMakeLists.txt | 2 +- Evade2/old/GameState/enemies/GBossSprite.cpp | 2 +- Evade2/old/GameState/enemies/GEnemySprite.cpp | 2 +- Evade2/src/GGame.cpp | 6 +- Evade2/src/GGame.h | 21 +- Evade2/src/GResources.h | 11 +- Evade2/src/Game.h | 16 +- Evade2/src/{ => GameState}/GCamera.cpp | 12 +- Evade2/src/{ => GameState}/GCamera.h | 12 +- Evade2/src/GameState/GEnemyBulletProcess.cpp | 47 +++ Evade2/src/GameState/GEnemyBulletProcess.h | 30 ++ Evade2/src/GameState/GEnemyProcess.cpp | 291 ++++++++++++++++++ Evade2/src/GameState/GEnemyProcess.h | 59 ++++ Evade2/src/GameState/GGamePlayfield.cpp | 13 +- Evade2/src/GameState/GGameState.cpp | 21 +- Evade2/src/GameState/GGameState.h | 4 + Evade2/src/GameState/GPlayerBulletProcess.cpp | 52 ++++ Evade2/src/GameState/GPlayerBulletProcess.h | 23 ++ Evade2/src/GameState/GPlayerProcess.cpp | 124 ++++---- Evade2/src/GameState/GPlayerProcess.h | 14 +- Evade2/src/common/GVectorSprite.cpp | 54 ++-- Evade2/src/common/GVectorSprite.h | 31 +- Evade2/src/img/ebomb_img.h | 2 +- Evade2/src/img/ebullet_img.h | 2 +- Evade2/src/main.cpp | 23 ++ 25 files changed, 713 insertions(+), 161 deletions(-) rename Evade2/src/{ => GameState}/GCamera.cpp (85%) rename Evade2/src/{ => GameState}/GCamera.h (50%) create mode 100644 Evade2/src/GameState/GEnemyBulletProcess.cpp create mode 100644 Evade2/src/GameState/GEnemyBulletProcess.h create mode 100644 Evade2/src/GameState/GEnemyProcess.cpp create mode 100644 Evade2/src/GameState/GEnemyProcess.h create mode 100644 Evade2/src/GameState/GPlayerBulletProcess.cpp create mode 100644 Evade2/src/GameState/GPlayerBulletProcess.h create mode 100644 Evade2/src/main.cpp diff --git a/Evade2/CMakeLists.txt b/Evade2/CMakeLists.txt index e18aa7b..85a8524 100644 --- a/Evade2/CMakeLists.txt +++ b/Evade2/CMakeLists.txt @@ -65,7 +65,7 @@ ADD_EXECUTABLE( Resources.bin ${CREATIVE_ENGINE_SOURCE_FILES} ${EVADE2_SRC} - creative-engine/src/main.cpp src/GameState/GGameState.cpp src/GameState/GGameState.h src/GameState/GGamePlayfield.cpp src/GameState/GGamePlayfield.h) + src/GameState/GGameState.cpp src/GameState/GGameState.h src/GameState/GGamePlayfield.cpp src/GameState/GGamePlayfield.h src/GameState/GPlayerBulletProcess.cpp src/GameState/GPlayerBulletProcess.h src/main.cpp src/GameState/GEnemyProcess.cpp src/GameState/GEnemyProcess.h src/GameState/GEnemyBulletProcess.cpp src/GameState/GEnemyBulletProcess.h) ProcessorCount(N) if (NOT N EQUAL 0) diff --git a/Evade2/old/GameState/enemies/GBossSprite.cpp b/Evade2/old/GameState/enemies/GBossSprite.cpp index 30c117f..280171e 100644 --- a/Evade2/old/GameState/enemies/GBossSprite.cpp +++ b/Evade2/old/GameState/enemies/GBossSprite.cpp @@ -2,7 +2,7 @@ #include "GResources.h" #include "GBossSprite.h" #include "GPlayer.h" -#include "GCamera.h" +#include "GameState/GCamera.h" static const TFloat z_dist = 256; static const TFloat frames = 32; diff --git a/Evade2/old/GameState/enemies/GEnemySprite.cpp b/Evade2/old/GameState/enemies/GEnemySprite.cpp index 19c91c1..5648c71 100644 --- a/Evade2/old/GameState/enemies/GEnemySprite.cpp +++ b/Evade2/old/GameState/enemies/GEnemySprite.cpp @@ -2,7 +2,7 @@ #include "GResources.h" #include "GEnemySprite.h" #include "GPlayer.h" -#include "GCamera.h" +#include "GameState/GCamera.h" const TInt8 *enemy_graphic(TInt16 n) { diff --git a/Evade2/src/GGame.cpp b/Evade2/src/GGame.cpp index 4f27f0c..670308b 100644 --- a/Evade2/src/GGame.cpp +++ b/Evade2/src/GGame.cpp @@ -1,7 +1,7 @@ #include "Game.h" #include "GGame.h" //#include "GPlayer.h" -#include "GCamera.h" +#include "GameState/GCamera.h" #include "GResources.h" #include "./GameState/GGameState.h" @@ -24,7 +24,8 @@ TBool GGame::mDebug = EFalse; GGame::GGame() { printf("Construct GGame\n"); - gGameEngine = new GGameState(); + mDifficulty = 1; + mState = GAME_STATE_GAME; #if 0 mLocalData = ENull; mLocalDataSize = 0; @@ -223,6 +224,7 @@ TBool GGame::IsGameState() { void GGame::Run() { printf("run\n"); + gGameEngine = new GGameState(); TBool done = EFalse; while (!done) { Random(); // randomize diff --git a/Evade2/src/GGame.h b/Evade2/src/GGame.h index 6031993..0759679 100644 --- a/Evade2/src/GGame.h +++ b/Evade2/src/GGame.h @@ -6,6 +6,7 @@ //#include "GStarFieldProcess.h" class BGameEngine; + class BFont; enum { @@ -39,30 +40,26 @@ class GGame : public BApplication { TInt GetState(); -// void ToggleInGameMenu(); -// void ToggleInventory(); -// void ToggleDebugMenu(); TBool IsGameState(); + BGameEngine *CurrentState(); + TUint16 mWave; + TUint16 mKills; + TUint8 mDifficulty; static TBool mDebug; protected: -protected: - TInt mState; - TInt mNextState; -// TAny *mLocalData; // arbitrary local data that is passed to SetState. -// TUint32 mLocalDataSize; + TInt mState; + TInt mNextState; BGameEngine *mGameMenu; -// BGameEngine *mInventory; -// BGameEngine *mDebugMenu; TRGB mShmoo; // GStarFieldProcess *mStarField; }; -extern GGame *gGame; +extern GGame *gGame; extern BGameEngine *gGameEngine; -extern BFont *gFont8x8, *gFont16x16; +extern BFont *gFont8x8, *gFont16x16; #endif //BRICKOUT_GGAME_H diff --git a/Evade2/src/GResources.h b/Evade2/src/GResources.h index fbe9007..3bbf60d 100644 --- a/Evade2/src/GResources.h +++ b/Evade2/src/GResources.h @@ -122,11 +122,12 @@ const TUint8 COLOR_SPACE = 215; const TUint8 SHMOO_COLOR = 216; const TUint8 BULLET_COLOR = 217; const TUint8 EBULLET_COLOR = 218; -const TUint8 BOSS_COLOR = 219; -const TUint8 ASSAULT_COLOR = 220; -const TUint8 BOMBER_COLOR = 221; -const TUint8 SCOUT_COLOR = 222; -const TUint8 STAR_COLOR = 223; +const TUint8 BOMB_COLOR = 219; +const TUint8 BOSS_COLOR = 220; +const TUint8 ASSAULT_COLOR = 221; +const TUint8 BOMBER_COLOR = 222; +const TUint8 SCOUT_COLOR = 223; +const TUint8 STAR_COLOR = 224; #define MAX_BBITMAP 5 diff --git a/Evade2/src/Game.h b/Evade2/src/Game.h index 4e0d76d..ed227e0 100644 --- a/Evade2/src/Game.h +++ b/Evade2/src/Game.h @@ -5,12 +5,16 @@ #define WIDTH 640 #define HEIGHT 400 -#define SCREEN_WIDTH 320 -#define SCREEN_HEIGHT 200 -#define SCREEN_DEPTH 8 +//#define SCREEN_WIDTH 320 +//#define SCREEN_HEIGHT 200 +//#define SCREEN_DEPTH 8 -const float CAMERA_VZ = 4; -const float DELTACONTROL = 11; +const TFloat CAMERA_VZ = 4; +const TFloat DELTACONTROL = 11; +const TInt8 MAX_BULLETS = 6; + +#define BANK_LEFT TUint32(1< diff --git a/Evade2/src/GCamera.cpp b/Evade2/src/GameState/GCamera.cpp similarity index 85% rename from Evade2/src/GCamera.cpp rename to Evade2/src/GameState/GCamera.cpp index e01328b..f2fee77 100644 --- a/Evade2/src/GCamera.cpp +++ b/Evade2/src/GameState/GCamera.cpp @@ -4,13 +4,13 @@ // -TFloat GCamera::mX = 0; -TFloat GCamera::mY = 0; -TFloat GCamera::mZ = 0; +TFloat GCamera::x = 0; +TFloat GCamera::y = 0; +TFloat GCamera::z = 0; -TFloat GCamera::mVX = 0; -TFloat GCamera::mVY = 0; -TFloat GCamera::mVZ = CAMERA_VZ; +TFloat GCamera::vx = 0; +TFloat GCamera::vy = 0; +TFloat GCamera::vz = CAMERA_VZ; // //Camera::Camera() { diff --git a/Evade2/src/GCamera.h b/Evade2/src/GameState/GCamera.h similarity index 50% rename from Evade2/src/GCamera.h rename to Evade2/src/GameState/GCamera.h index a9a8565..8253006 100644 --- a/Evade2/src/GCamera.h +++ b/Evade2/src/GameState/GCamera.h @@ -6,19 +6,19 @@ class GCamera { public: - static TFloat mX, mY, mZ; - static TFloat mVX, mVY, mVZ; + static TFloat x,y,z; + static TFloat vx,vy,vz; public: static void Move() { - GCamera::mX += GCamera::mVX; - GCamera::mY += GCamera::mVY; - GCamera::mZ += GCamera::mVZ; + GCamera::x += GCamera::vx; + GCamera::y += GCamera::vy; + GCamera::z += GCamera::vz; } static TBool CollidesWith(GVectorSprite *aVSprite) { // If enemy bullet collides with player - if (abs(aVSprite->mZ - GCamera::mZ) < abs(aVSprite->mVZ) && abs(aVSprite->mX - GCamera::mX) < 64 && abs(aVSprite->mY - GCamera::mY) < 64) { + if (abs(aVSprite->z - GCamera::z) < abs(aVSprite->vz) && abs(aVSprite->x - GCamera::x) < 64 && abs(aVSprite->y - GCamera::y) < 64) { return ETrue; } return EFalse; diff --git a/Evade2/src/GameState/GEnemyBulletProcess.cpp b/Evade2/src/GameState/GEnemyBulletProcess.cpp new file mode 100644 index 0000000..1074b7a --- /dev/null +++ b/Evade2/src/GameState/GEnemyBulletProcess.cpp @@ -0,0 +1,47 @@ +// +// Created by Michael Schwartz on 11/2/20. +// + +#include "GEnemyBulletProcess.h" +#include "GCamera.h" +#include "img/ebomb_img.h" +#include "img/ebullet_img.h" + +GEnemyBulletProcess::GEnemyBulletProcess(GVectorSprite *enemy, TInt8 type) { + const TFloat FRAMES = 90 / gGame->mDifficulty; + mSprite = new GVectorSprite(OTYPE_ENEMY_BULLET); + mSprite->mLines = (type == EBULLET_BOMB) ? ebomb_img : ebullet_img; + mSprite->mColor = (type == EBULLET_BOMB) ? BOMB_COLOR : EBULLET_COLOR; + mSprite->mTimer = 256 * 2; // timeout + mSprite->x = enemy->x - 8; + mSprite->y = enemy->y - 8; + mSprite->z = enemy->z; + mSprite->vx = (GCamera::x - mSprite->x) / FRAMES; + mSprite->vy = (GCamera::y - mSprite->y) / FRAMES; + mSprite->vz = GCamera::vz - (mSprite->z - GCamera::z) / FRAMES; +// printf("Bullet vx,vy,vz = %f,%f,%f mState(%d)\n", mSprite->vx, mSprite->vy, mSprite->vz, mSprite->mTimer); + gGameEngine->AddSprite(mSprite); +} + +GEnemyBulletProcess::~GEnemyBulletProcess() noexcept { + mSprite->Remove(); + delete mSprite; + mSprite = ENull; +} + +TBool GEnemyBulletProcess::RunBefore() { + mSprite->mTheta += (mSprite->mLines == ebomb_img) ? mSprite->x : 40; + return ETrue; +} + +TBool GEnemyBulletProcess::RunAfter() { + if (mSprite->BehindCamera()) { +// printf("RunAfter Behind\n"); + return EFalse; + } + if (--mSprite->mTimer <= 0) { +// printf("RunAfter(%d) \n", mSprite->mTimer); + return EFalse; + } + return ETrue; +} \ No newline at end of file diff --git a/Evade2/src/GameState/GEnemyBulletProcess.h b/Evade2/src/GameState/GEnemyBulletProcess.h new file mode 100644 index 0000000..29851db --- /dev/null +++ b/Evade2/src/GameState/GEnemyBulletProcess.h @@ -0,0 +1,30 @@ +// +// Created by Michael Schwartz on 11/2/20. +// + +#ifndef EVADE2_GENEMYBULLETPROCESS_H +#define EVADE2_GENEMYBULLETPROCESS_H + +#include "Game.h" +#include "GVectorSprite.h" + +#define EBULLET_BULLET 1 +#define EBULLET_BOMB 2 + +class GEnemyBulletProcess : public BProcess { +public: + GEnemyBulletProcess(GVectorSprite *enemy, TInt8 type); + + ~GEnemyBulletProcess(); + +public: + TBool RunBefore(); + + TBool RunAfter(); + +protected: + GVectorSprite *mSprite; +}; + + +#endif //EVADE2_GENEMYBULLETPROCESS_H diff --git a/Evade2/src/GameState/GEnemyProcess.cpp b/Evade2/src/GameState/GEnemyProcess.cpp new file mode 100644 index 0000000..de9e9a5 --- /dev/null +++ b/Evade2/src/GameState/GEnemyProcess.cpp @@ -0,0 +1,291 @@ +// +// Created by Michael Schwartz on 11/2/20. +// + +#include "GGame.h" +#include "GEnemyProcess.h" +#include "GEnemyBulletProcess.h" +#include "GCamera.h" +#include "img/enemy_assault_1_img.h" +#include "img/enemy_heavy_bomber_1_img.h" +#include "img/enemy_scout_1_img.h" + +#define FIRE_TIME (60 / gGame->mDifficulty + Random(1, 60 / gGame->mDifficulty)) + +GEnemyProcess::GEnemyProcess() { + printf("Spawn GEmenyProcess\n"); + mSprite = new GVectorSprite(OTYPE_ENEMY); + gGameEngine->AddSprite(mSprite); + respawn(); +} + +GEnemyProcess::~GEnemyProcess() noexcept { + mSprite->Remove(); + delete mSprite; + mSprite = ENull; +} + +TBool GEnemyProcess::death() { + if (mSprite->flags & OFLAG_COLLISION) { + gGame->mKills++; + mSprite->flags &= OFLAG_EXPLODE; + mSprite->mState = 0; + return ETrue; + } + return EFalse; +} + +void GEnemyProcess::fire() { + mSprite->mTimer--; + if (mSprite->mTimer <= 0) { + if (GCamera::vx || GCamera::vy) { + mSprite->mTimer = 1; + return; + } + // FIRE! +// printf("Fire!!!\n"); + gGameEngine->AddProcess(new GEnemyBulletProcess(mSprite, Random(0, 5) ? EBULLET_BULLET : EBULLET_BOMB)); + mSprite->mTimer = FIRE_TIME; + } else { + // TODO: @jay why is this being decremented a second time? + mSprite->mTimer--; + } +} + +#define DELTA_THETA 8 + +void GEnemyProcess::bank(TInt16 delta) { + if (mSprite->flags & BANK_LEFT) { + mSprite->mTheta -= DELTA_THETA; + if (mSprite->mTheta < -delta) { + mSprite->flags &= ~BANK_LEFT; + } + } else { + mSprite->mTheta += DELTA_THETA; + if (mSprite->mTheta > delta) { + mSprite->flags |= BANK_LEFT; + } + } +} + +void GEnemyProcess::respawn() { + mSprite->mTimer = Random(gGame->mWave > 6 ? 30 : 30, 60) + 30; +// printf("RESPAWN %d\n", mSprite->mTimer); + + mState = ESTATE_WAITINIT; +} + +void GEnemyProcess::init_assault(TBool left) { + TFloat angle = left ? 0 : (2 * PI); + mSprite->x = cos(angle) * 256; + mSprite->z = GCamera::z + sin(angle) * 256; + mSprite->y = GCamera::y; // + 64 - random(0, 128); + mSprite->vx = mSprite->vy = mSprite->vz = 0; + mSprite->mState = 0; + mSprite->mColor = ASSAULT_COLOR; +} + +/** + * Initialize object for scout enemy + */ +void GEnemyProcess::init_scout() { + mSprite->x = GCamera::x + Random(-256, 256); + mSprite->y = GCamera::y + Random(-256, 256); + mSprite->z = GCamera::z + 1024; + mSprite->vz = CAMERA_VZ - 12; + mSprite->vx = mSprite->vy = 0; + mSprite->mTheta = Random(-50, 50); + mSprite->mColor = SCOUT_COLOR; +} + +/** + * Initialize object for bomber enemy + */ +void GEnemyProcess::init_bomber() { + mSprite->x = GCamera::x + 128 - Random(0, 127); + mSprite->y = GCamera::y + 128 - Random(0, 127); + mSprite->z = GCamera::z - 30; + mSprite->vz = CAMERA_VZ + 1 + gGame->mWave; + mSprite->vx = mSprite->vy = 0; + mSprite->mColor = BOMBER_COLOR; +} + +void GEnemyProcess::init() { + mSprite->flags &= ~OFLAG_EXPLODE; + mSprite->flags &= ~OFLAG_COLLISION; + mSprite->mTimer = FIRE_TIME; + mSprite->mTheta = 0; + + // One enemy type enters per wave + switch (Random(0, (gGame->mWave > 3) ? 3 : gGame->mWave)) { + case 0: + mSprite->mLines = (const TInt8 *) &enemy_scout_1_img; + init_scout(); + mState = ESTATE_SEEK; + break; + case 1: + mSprite->mLines = (const TInt8 *) &enemy_heavy_bomber_1_img; + init_bomber(); + mState = ESTATE_EVADE; + break; + case 2: + mSprite->mLines = (const TInt8 *) &enemy_assault_1_img; + init_assault(Random() & 1); + mState = ESTATE_ORBIT; + break; + } + printf("init\n"); +} + +TBool GEnemyProcess::StateSeek() { + GVectorSprite *o = mSprite; + if (o->BehindCamera()) { + respawn(); + return ETrue; + } + if (death()) { + mState = ESTATE_EXPLODE; + return ETrue; + } + // bank(o); + fire(); + o->mTheta += 8; + if (o->z - GCamera::z < Random(256, 512)) { + o->mState = -1; + mState = ESTATE_RUNAWAY; +// me->sleep(1, run_away); + return ETrue; + } + + return ETrue; +} + +TBool GEnemyProcess::StateEvade() { + GVectorSprite *o = mSprite; + if (o->z - GCamera::z > 512) { + o->mState = 1; + mState = ESTATE_RUNAWAY; +// me->sleep(1, run_away); + return ETrue; + } + if (death()) { + mState = ESTATE_EXPLODE; +// me->sleep(1, explode); + return ETrue; + } + bank(15); + fire(); + return ETrue; +} + +TBool GEnemyProcess::StateOrbit() { + GVectorSprite *o = mSprite; + if (death()) { + mState = ESTATE_EXPLODE; + return ETrue; + } + fire(); + + if (o->flags & ORBIT_LEFT) { + o->mState -= gGame->mDifficulty; + if (o->mState < 0) { + o->mState = 0; + o->flags &= ~ORBIT_LEFT; + } + else { + o->mTheta -= 12; + } + } + else { + o->mState += gGame->mDifficulty; + if (o->mState > 180) { + o->mState = 180; + o->flags |= ORBIT_LEFT; + } + else { + o->mTheta += 12; + } + } + + TFloat rad = RADIANS(o->mState); + o->vy = (GCamera::y > o->y) ? -2 : 2; + o->y = GCamera::y; + o->x = cos(rad) * 256; + if (gGame->GetState() == GAME_STATE_GAME) { + o->z = GCamera::z + sin(rad) * 256; + } + +// me->sleep(1); + return ETrue; +} + +TBool GEnemyProcess::StateWaitInit() { + GVectorSprite *o = mSprite; + if (o->mTimer <= 0 && gGame->GetState() == GAME_STATE_GAME) { + init(); + return ETrue; + } + else { + o->mTimer = 1; + } + o->mTimer--; +// me->sleep(1); + return ETrue; +} + +TBool GEnemyProcess::StateRunAway() { + GVectorSprite *o = mSprite; + if (gGame->GetState() != GAME_STATE_GAME) { + o->vz += o->mState * 8; + } + else { + o->vz += o->mState; + } + o->vx += o->vx > 0 ? .1 : -.1; + o->vy += o->vy > 0 ? .1 : -.1; + if (o->BehindCamera() || (o->z - GCamera::z) > 1024) { + respawn(); + return ETrue; + } + if (death()) { + mState = ESTATE_EXPLODE; +// me->sleep(1, explode); + return ETrue; + } + bank(); + fire(); +// me->sleep(1); + return ETrue; +} + +TBool GEnemyProcess::StateExplode() { + mSprite->flags |= OFLAG_EXPLODE; + mSprite->mState++; + if (mSprite->BehindCamera() || mSprite->mState > 50) { + respawn(); + } + return ETrue; +} + +TBool GEnemyProcess::RunBefore() { + return ETrue; +} + +TBool GEnemyProcess::RunAfter() { + switch (mState) { + case ESTATE_SEEK: + return StateSeek(); + case ESTATE_EVADE: + return StateEvade(); + case ESTATE_ORBIT: + return StateOrbit(); + case ESTATE_WAITINIT: + return StateWaitInit(); + case ESTATE_RUNAWAY: + return StateRunAway(); + case ESTATE_EXPLODE: + return StateExplode(); + default: + Panic("Bad Genemy State %d", mState); + } +} diff --git a/Evade2/src/GameState/GEnemyProcess.h b/Evade2/src/GameState/GEnemyProcess.h new file mode 100644 index 0000000..5e47fcb --- /dev/null +++ b/Evade2/src/GameState/GEnemyProcess.h @@ -0,0 +1,59 @@ +// +// Created by Michael Schwartz on 11/2/20. +// + +#ifndef EVADE2_GENEMYPROCESS_H +#define EVADE2_GENEMYPROCESS_H + +#include "Game.h" +#include "GVectorSprite.h" + +#define ENEMY_ASSAULT 0 +#define ENEMY_BOMBER 1 +#define ENEMY_SCOUT 2 + +enum EState { + ESTATE_SEEK, + ESTATE_EVADE, + ESTATE_ORBIT, + ESTATE_WAITINIT, + ESTATE_RUNAWAY, + ESTATE_EXPLODE, +}; + +class GEnemyProcess : public BProcess { +public: + GEnemyProcess(); + ~GEnemyProcess(); + +public: + TBool RunBefore(); + TBool RunAfter(); + +private: + void init_assault(TBool left); + void init_scout(); + void init_bomber(); + void init(); + void respawn(); + TBool death(); + void fire(); + void bank(TInt16 delta = 45); + +protected: + GVectorSprite *mSprite; + +protected: + TBool StateSeek(); + TBool StateEvade(); + TBool StateOrbit(); + TBool StateWaitInit(); + TBool StateRunAway(); + TBool StateExplode(); +protected: + EState mState; + +}; + + +#endif //EVADE2_GENEMYPROCESS_H diff --git a/Evade2/src/GameState/GGamePlayfield.cpp b/Evade2/src/GameState/GGamePlayfield.cpp index 5f3c90d..dde66e1 100644 --- a/Evade2/src/GameState/GGamePlayfield.cpp +++ b/Evade2/src/GameState/GGamePlayfield.cpp @@ -17,7 +17,7 @@ GGamePlayfield::~GGamePlayfield() noexcept { void GGamePlayfield::Render() { gDisplay.renderBitmap->Clear(0); - TFloat cz = GCamera::mZ, + TFloat cz = GCamera::z, sw = TFloat(SCREEN_WIDTH), sh = TFloat(SCREEN_HEIGHT); @@ -29,8 +29,8 @@ void GGamePlayfield::Render() { } TFloat ratioX = sw / (zz + sw); TFloat ratioY = sh / (zz + sh); - TFloat x = (sw / 2) - (mStarX[i] - GCamera::mX) * ratioX; - TFloat y = (sh / 2) - (mStarY[i] - GCamera::mY) * ratioY; + TFloat x = (sw / 2) - (mStarX[i] - GCamera::x) * ratioX; + TFloat y = (sh / 2) - (mStarY[i] - GCamera::y) * ratioY; if (x < 0) { // printf("InitStar x %f < 0\n", x); @@ -51,8 +51,7 @@ void GGamePlayfield::Render() { } void GGamePlayfield::InitStar(TInt aIndex) { - mStarX[aIndex] = 256 - Random(0, 512) + GCamera::mX; - mStarY[aIndex] = 256 - Random(0, 512) + GCamera::mY; - mStarZ[aIndex] = GCamera::mZ + Random(200, 512); - + mStarX[aIndex] = TFloat(256) - Random(0, 512) + GCamera::x; + mStarY[aIndex] = TFloat(256) - Random(0, 512) + GCamera::y; + mStarZ[aIndex] = GCamera::z + Random(200, 512); } \ No newline at end of file diff --git a/Evade2/src/GameState/GGameState.cpp b/Evade2/src/GameState/GGameState.cpp index 8884bc3..37c1cc6 100644 --- a/Evade2/src/GameState/GGameState.cpp +++ b/Evade2/src/GameState/GGameState.cpp @@ -4,16 +4,33 @@ #include "GGameState.h" #include "GGamePlayfield.h" +#include "GPlayerProcess.h" +#include "GEnemyProcess.h" + +GGameState *gGameState; GGameState::GGameState() : BGameEngine(gViewPort) { + gGameEngine = this; + gGameState = this; mPlayfield = new GGamePlayfield(); // set colors gDisplay.SetColor(COLOR_BLACK, 0,0,0); for (TInt i=1; i<256; i++) { gDisplay.SetColor(i, 255,255,255); } -// gDisplay.SetColor(COLOR_WHITE, 255,255,255); -// gDisplay.SetColor(COLOR_STAR, 255,255,255); + gDisplay.SetColor(COLOR_WHITE, 255, 255, 255); + gDisplay.SetColor(ASSAULT_COLOR, 255, 50, 50); + gDisplay.SetColor(BOMBER_COLOR, 50, 255, 50); + gDisplay.SetColor(SCOUT_COLOR, 255, 50, 255); + gDisplay.SetColor(EBULLET_COLOR, 50, 50, 255); + gDisplay.SetColor(BOMB_COLOR, 255, 255, 50); + AddProcess(new GEnemyProcess()); + AddProcess(new GEnemyProcess()); + AddProcess(new GEnemyProcess()); + mPlayerProcess = new GPlayerProcess(); + AddProcess(mPlayerProcess); + gDisplay.SetColor(COLOR_WHITE, 255,255,255); + gDisplay.SetColor(COLOR_STAR, 255,255,255); } GGameState::~GGameState() { diff --git a/Evade2/src/GameState/GGameState.h b/Evade2/src/GameState/GGameState.h index 73b10bb..6b35827 100644 --- a/Evade2/src/GameState/GGameState.h +++ b/Evade2/src/GameState/GGameState.h @@ -7,13 +7,17 @@ #include +class GPlayerProcess; + class GGameState : public BGameEngine { public: GGameState(); ~GGameState(); public: // void GameLoop() OVERRIDE; + GPlayerProcess *mPlayerProcess; }; +extern GGameState *gGameState; #endif //EVADE2_GGAMESTATE_H diff --git a/Evade2/src/GameState/GPlayerBulletProcess.cpp b/Evade2/src/GameState/GPlayerBulletProcess.cpp new file mode 100644 index 0000000..26eab7b --- /dev/null +++ b/Evade2/src/GameState/GPlayerBulletProcess.cpp @@ -0,0 +1,52 @@ +// +// Created by Michael Schwartz on 11/2/20. +// + +#include "GGameState.h" +#include "GPlayerProcess.h" +#include "GPlayerBulletProcess.h" +#include "GCamera.h" + +#include "img/bullet_img.h" + +const TFloat BULLET_VZ = 15; + +GPlayerBulletProcess::GPlayerBulletProcess(TFloat deltaX, TFloat deltaY, TBool alt) { + mSprite = new GVectorSprite(OTYPE_PLAYER_BULLET); + if (alt) { + mSprite->x = GCamera::x + 28; + mSprite->y = GCamera::y - 28; + mSprite->z = GCamera::z; + mSprite->mState = 20; + } else { + mSprite->x = GCamera::x - 28; + mSprite->y = GCamera::y - 28; + mSprite->z = GCamera::z; + mSprite->mState = -20; + } + mSprite->vx = deltaX; + mSprite->vy = deltaY; + mSprite->vz = GCamera::vz + BULLET_VZ; + mSprite->mLines = bullet_img; + gGameEngine->AddSprite(mSprite); +} + +GPlayerBulletProcess::~GPlayerBulletProcess() noexcept { + printf("BUllet death\n"); + gGameState->mPlayerProcess->mNumBullets--; + mSprite->Remove(); + delete mSprite; + mSprite = ENull; +} + +TBool GPlayerBulletProcess::RunBefore() { + mSprite->mTheta += mSprite->mState; + return ETrue; +} + +TBool GPlayerBulletProcess::RunAfter() { + if (mSprite->z - GCamera::z > 512) { + return EFalse; + } + return ETrue; +} \ No newline at end of file diff --git a/Evade2/src/GameState/GPlayerBulletProcess.h b/Evade2/src/GameState/GPlayerBulletProcess.h new file mode 100644 index 0000000..ac11566 --- /dev/null +++ b/Evade2/src/GameState/GPlayerBulletProcess.h @@ -0,0 +1,23 @@ +// +// Created by Michael Schwartz on 11/2/20. +// + +#ifndef EVADE2_GPLAYERBULLETPROCESS_H +#define EVADE2_GPLAYERBULLETPROCESS_H + +#include "Game.h" +#include "GVectorSprite.h" + +class GPlayerBulletProcess : public BProcess { +public: + GPlayerBulletProcess(TFloat deltaX, TFloat deltaY, TBool alt); + ~GPlayerBulletProcess() OVERRIDE; +public: + TBool RunBefore() OVERRIDE; + TBool RunAfter() OVERRIDE; +protected: + GVectorSprite *mSprite; +}; + + +#endif //EVADE2_GPLAYERBULLETPROCESS_H diff --git a/Evade2/src/GameState/GPlayerProcess.cpp b/Evade2/src/GameState/GPlayerProcess.cpp index 5f1f042..a742e19 100644 --- a/Evade2/src/GameState/GPlayerProcess.cpp +++ b/Evade2/src/GameState/GPlayerProcess.cpp @@ -5,7 +5,7 @@ #include "Game.h" #include "GCamera.h" - +#include "GPlayerBulletProcess.h" #include "img/hud_console_img.h" //TODO: Put in own files @@ -25,11 +25,14 @@ const TUint8 crosshair_right_4x8[] = { #define MAX_LIFE 100 GPlayerProcess::GPlayerProcess() { - GCamera::mVZ = CAMERA_VZ; - power = MAX_POWER; - shield = MAX_LIFE; - num_bullets = 0; - flags = 0; + color = COLOR_WHITE; + GCamera::vz = CAMERA_VZ; + power = MAX_POWER; + shield = MAX_LIFE; + mNumBullets = 0; + mAlt = EFalse; + mHit = EFalse; + printf("screen %d,%d\n", gDisplay.renderBitmap->Width(), gDisplay.renderBitmap->Height()); } void GPlayerProcess::DrawPixel(TFloat x, TFloat y) { @@ -41,7 +44,7 @@ void GPlayerProcess::DrawLine(TFloat x1, TFloat y1, TFloat x2, TFloat y2) { } void GPlayerProcess::DrawBitmap(TInt16 x, TInt16 y, const TUint8 *bitmap, TUint8 w, TUint8 h, TUint8 color) { - #if 0 +#if 0 // no need to draw at all if we're offscreen if (x + w < 0 || x > WIDTH - 1 || y + h < 0 || y > HEIGHT - 1) return; @@ -86,16 +89,15 @@ void GPlayerProcess::DrawBitmap(TInt16 x, TInt16 y, const TUint8 *bitmap, TUint8 } } } - #endif +#endif } void GPlayerProcess::hit(TInt8 amount) { shield -= amount; if (shield <= 0) { // ProcessManager::birth(GameOver::entry); - } - else { - flags |= PLAYER_FLAG_HIT; + } else { + mHit = ETrue; // Sound::play_sound(SFX_PLAYER_HIT_BY_ENEMY); } } @@ -113,40 +115,43 @@ void GPlayerProcess::recharge_power() { } TBool GPlayerProcess::RunBefore() { - if (gGame->GetState() == GAME_STATE_GAME) { + if (gGame->GetState() != GAME_STATE_GAME) { // if (game_mode != MODE_GAME) { - GCamera::mVX = GCamera::mVY = 0; + GCamera::vx = GCamera::vy = 0; return ETrue; } if (gControls.WasPressed(CONTROL_FIRE)) { - TInt8 deltaX = 0, - deltaY = 0; + if (mNumBullets < MAX_BULLETS) { + + TInt8 deltaX = 0, + deltaY = 0; + + deltaX = gControls.IsPressed(CONTROL_JOYRIGHT) ? -12 : deltaX; + deltaX = gControls.IsPressed(CONTROL_JOYLEFT) ? 12 : deltaX; + + deltaY = gControls.IsPressed(CONTROL_JOYUP) ? -11 : deltaY; + deltaY = gControls.IsPressed(CONTROL_JOYDOWN) ? 13 : deltaY; - deltaX = gControls.IsPressed(CONTROL_JOYRIGHT) ? -12 : deltaX; - deltaX = gControls.IsPressed(CONTROL_JOYLEFT) ? 12 : deltaX; - deltaY = gControls.IsPressed(CONTROL_JOYUP) ? -11 : deltaY; - deltaY = gControls.IsPressed(CONTROL_JOYDOWN) ? 13 : deltaY; + gGameEngine->AddProcess(new GPlayerBulletProcess(deltaX, deltaY, mAlt)); - // Bullet::fire(deltaX, deltaY, Player::flags & PLAYER_FLAG_ALT); - flags ^= PLAYER_FLAG_ALT; + mAlt = !mAlt; + } } if (gControls.IsPressed(CONTROL_BURST)) { if (power > 0) { - GCamera::mVZ = CAMERA_VZ * 2; + GCamera::vz = CAMERA_VZ * 2; power--; if (power < 0) { power = 0; } + } else { + GCamera::vz = CAMERA_VZ; } - else { - GCamera::mVZ = CAMERA_VZ; - } - } - else { - GCamera::mVZ = CAMERA_VZ; + } else { + GCamera::vz = CAMERA_VZ; power++; if (power > MAX_POWER) { power = MAX_POWER; @@ -154,23 +159,19 @@ TBool GPlayerProcess::RunBefore() { } if (gControls.IsPressed(CONTROL_JOYRIGHT)) { - GCamera::mVX = -DELTACONTROL; - } - else if (gControls.IsPressed(CONTROL_JOYLEFT)) { - GCamera::mVX = DELTACONTROL; - } - else { - GCamera::mVX = 0; + GCamera::vx = -DELTACONTROL; + } else if (gControls.IsPressed(CONTROL_JOYLEFT)) { + GCamera::vx = DELTACONTROL; + } else { + GCamera::vx = 0; } if (gControls.IsPressed(CONTROL_JOYDOWN)) { - GCamera::mVY = DELTACONTROL; - } - else if (gControls.IsPressed(CONTROL_JOYUP)) { - GCamera::mVY = -DELTACONTROL; - } - else { - GCamera::mVY = 0; + GCamera::vy = DELTACONTROL; + } else if (gControls.IsPressed(CONTROL_JOYUP)) { + GCamera::vy = -DELTACONTROL; + } else { + GCamera::vy = 0; } return ETrue; } @@ -182,7 +183,7 @@ TBool GPlayerProcess::RunBefore() { #ifdef ENABLE_HUD_MOVEMENTS // 13 == full. Anything less, and we draw "less meter" -static void drawMeter(TInt8 side, TInt8 value, TInt8 deltaXMeter, TInt8 deltaYMeter) { +void DrawMeter(TInt8 side, TInt8 value, TInt8 deltaXMeter, TInt8 deltaYMeter) { //start at X:14 // Draw 2 lines, skip one line, iterate 13 total times @@ -223,7 +224,7 @@ static void drawMeter(TInt8 side, TInt8 value, TInt8 deltaXMeter, TInt8 deltaYMe #else // 13 == full. Anything less, and we draw "less meter" -void GPlayerProcess::drawMeter(TInt8 side, TInt8 value) { +void GPlayerProcess::DrawMeter(TInt8 side, TInt8 value) { //start at X:14 // Draw 2 lines, skip one line, iterate 13 total times @@ -238,23 +239,20 @@ void GPlayerProcess::drawMeter(TInt8 side, TInt8 value) { if (i >= value) { DrawPixel(0, y); DrawPixel(0, y + 1); - } - else { + } else { DrawLine(0, y, 2, y); DrawLine(0, y + 1, 3, y + 1); } y -= 3; } - } - else { // RIGHT + } else { // RIGHT for (TInt8 i = 0; i < 10; i++) { if (i >= value) { - DrawPixel(127, y); - DrawPixel(127, y + 1); - } - else { - DrawLine(126, y, 128, y); - DrawLine(125, y + 1, 128, y + 1); + DrawPixel(SCREEN_WIDTH-1, y); + DrawPixel(SCREEN_WIDTH-1, y + 1); + } else { + DrawLine(SCREEN_WIDTH-2, y, SCREEN_WIDTH, y); + DrawLine(SCREEN_WIDTH-3, y + 1, SCREEN_WIDTH, y + 1); } y -= 3; } @@ -264,9 +262,12 @@ void GPlayerProcess::drawMeter(TInt8 side, TInt8 value) { #endif // #if ENABLE_HUD_MOVEMENTS TBool GPlayerProcess::RunAfter() { - // TODO: swap background black -> white -> black - // arduboy.invert(flags & PLAYER_FLAG_HIT); - flags &= ~PLAYER_FLAG_HIT; + if (mHit) { + gDisplay.SetColor(0, 255, 255, 255); + } else { + gDisplay.SetColor(0, 0, 0, 0); + } + mHit = EFalse; #ifdef ENABLE_HUD_MOVEMENTS TInt8 consoleX = 40, @@ -311,14 +312,15 @@ TBool GPlayerProcess::RunAfter() { DrawBitmap(53 + deltaXCrossHairs, 30 + deltaYCrossHairs, crosshair_left_4x8, 4, 8); DrawBitmap(72 + deltaXCrossHairs, 30 + deltaYCrossHairs, crosshair_right_4x8, 4, 8); - drawMeter(0, shield, deltaXMeter, deltaYMeter); - drawMeter(1, power, deltaXMeter, deltaYMeter); + DrawMeter(0, shield, deltaXMeter, deltaYMeter); + DrawMeter(1, power, deltaXMeter, deltaYMeter); #else DrawBitmap(40, 58, hud_console_img, 0x30, 0x08); - drawMeter(0, shield); - drawMeter(1, power); + DrawMeter(0, shield); + DrawMeter(1, power); #endif + return ETrue; } diff --git a/Evade2/src/GameState/GPlayerProcess.h b/Evade2/src/GameState/GPlayerProcess.h index e7581de..a1a7433 100644 --- a/Evade2/src/GameState/GPlayerProcess.h +++ b/Evade2/src/GameState/GPlayerProcess.h @@ -7,7 +7,6 @@ #define PLAYER_FLAG_ALT (1 << 1) #include "Game.h" -#include class GPlayerProcess : public BProcess { public: @@ -16,9 +15,11 @@ class GPlayerProcess : public BProcess { public: TInt8 power; TInt8 shield; - TInt8 num_bullets; - TUint8 flags; + TInt8 mNumBullets; +// TUint8 flags; TUint8 color; + TBool mAlt; + TBool mHit; public: void recharge_shield(); @@ -29,11 +30,12 @@ class GPlayerProcess : public BProcess { void DrawLine(TFloat x1, TFloat y1, TFloat x2, TFloat y2); protected: - void drawMeter(TInt8 side, TInt8 value); + void DrawMeter(TInt8 side, TInt8 value); void DrawBitmap(TInt16 x, TInt16 y, const TUint8 *bitmap, TUint8 w, TUint8 h, TUint8 color = COLOR_WHITE); public: - TBool RunBefore(); - TBool RunAfter(); + TBool RunBefore() OVERRIDE; + TBool RunAfter() OVERRIDE; }; + #endif diff --git a/Evade2/src/common/GVectorSprite.cpp b/Evade2/src/common/GVectorSprite.cpp index 4246350..bce0577 100644 --- a/Evade2/src/common/GVectorSprite.cpp +++ b/Evade2/src/common/GVectorSprite.cpp @@ -1,9 +1,9 @@ #include "GVectorSprite.h" -#include "GCamera.h" +#include "GameState/GCamera.h" TBool GVectorSprite::ExplodeVectorGraphic(const TInt8 *graphic, TFloat x, TFloat y, - TFloat theta, TFloat scaleFactor, TInt8 step, TUint8 color) { + TFloat theta, TFloat scaleFactor, TInt8 step, TUint8 color) { graphic += 2; TBool drawn = false; @@ -13,7 +13,7 @@ TBool GVectorSprite::ExplodeVectorGraphic(const TInt8 *graphic, TFloat x, TFloat for (TInt8 i = 0; i < numRows; i++) { struct vec_segment_u8 seg; - TFloat x0, y0, x1, y1; + TFloat x0, y0, x1, y1; memcpy(&seg, graphic, sizeof(seg)); graphic += sizeof(seg); @@ -38,16 +38,15 @@ TBool GVectorSprite::ExplodeVectorGraphic(const TInt8 *graphic, TFloat x, TFloat } - TInt16 drawX1 = x0 * cost - y0 * sint + x, - drawY1 = y0 * cost + x0 * sint + y, - drawX2 = x1 * cost - y1 * sint + x, - drawY2 = y1 * cost + x1 * sint + y; + drawY1 = y0 * cost + x0 * sint + y, + drawX2 = x1 * cost - y1 * sint + x, + drawY2 = y1 * cost + x1 * sint + y; TBool xInBounds = (drawX1 >= 0) && (drawX1 <= DISPLAY_WIDTH) && (drawY1 >= 0) && (drawY1 < DISPLAY_HEIGHT), - yInBounds = (drawX2 >= 0) && (drawX2 <= DISPLAY_WIDTH) && (drawY2 >= 0) && (drawY2 < DISPLAY_HEIGHT); + yInBounds = (drawX2 >= 0) && (drawX2 <= DISPLAY_WIDTH) && (drawY2 >= 0) && (drawY2 < DISPLAY_HEIGHT); - if ((! xInBounds) && !(yInBounds)) { + if ((!xInBounds) && !(yInBounds)) { continue; } @@ -65,40 +64,41 @@ TBool GVectorSprite::ExplodeVectorGraphic(const TInt8 *graphic, TFloat x, TFloat } TBool GVectorSprite::Render(BViewPort *aViewPort) { - if (!mLines || mZ <= GCamera::mZ) { + if (!mLines || z <= GCamera::z) { // nothing to draw return EFalse; } - TFloat zz = (mZ - GCamera::mZ) * 2; + TFloat zz = (z - GCamera::z) * 2; TFloat ratio = 128 / (zz + 128); + TFloat sw = TFloat(SCREEN_WIDTH), + sh = TFloat(SCREEN_HEIGHT); - bool isEnemy = Type() == OTYPE_ENEMY; + bool isEnemy = Type() == OTYPE_ENEMY; // printf("is enemy = %i\n", isEnemy); - TFloat cx = (GCamera::mX - mX) * ratio + SCREEN_WIDTH / 2; - TFloat cy = (GCamera::mY - mY) * ratio + SCREEN_HEIGHT / 2; + TFloat cx = (GCamera::x - x) * ratio + sw / 2; + TFloat cy = (GCamera::y - y) * ratio + sh / 2; // uint8_t color = isEnemy ? 5 : 255; if (flags & OFLAG_EXPLODE) { ExplodeVectorGraphic(mLines, cx, cy, mTheta, 1 / ratio, mState, this->mColor); - } - else { + } else { bool drawn = DrawVectorGraphic(mLines, cx, cy, mTheta, 1 / ratio, this->mColor); if ((!drawn) && isEnemy) { // draw radar blip - TFloat dx = GCamera::mX - mX, - dy = GCamera::mY - mY, - angle = atan2(dy, dx); + TFloat dx = GCamera::x - x, + dy = GCamera::y - y, + angle = atan2(dy, dx); // printf("TODO: Fill Circle for enemy radar\n"); - aViewPort->FillCircle(gDisplay.renderBitmap, - (int16_t)(SCREEN_WIDTH / 2 + cos(angle) * 75), - (int16_t)(SCREEN_HEIGHT / 2 + sin(angle) * 75), - 3, - EBULLET_COLOR - ); + aViewPort->FillCircle(gDisplay.renderBitmap, + (int16_t) (sw / 2 + cos(angle) * 75), + (int16_t) (sh / 2 + sin(angle) * 75), + 3, + mColor + ); } } @@ -107,6 +107,6 @@ TBool GVectorSprite::Render(BViewPort *aViewPort) { } -TBool GVectorSprite::BehindCamera() { - return mZ <= GCamera::mZ; +TBool GVectorSprite::BehindCamera() { + return z <= GCamera::z; } \ No newline at end of file diff --git a/Evade2/src/common/GVectorSprite.h b/Evade2/src/common/GVectorSprite.h index 94546fa..cfacbb0 100644 --- a/Evade2/src/common/GVectorSprite.h +++ b/Evade2/src/common/GVectorSprite.h @@ -12,18 +12,18 @@ struct vec_segment_u8 { TInt8 y1; }; -#define FIRE_TIME (60 / Game::difficulty + random(1, 60 / Game::Game::difficulty)) +//#define FIRE_TIME (60 / Game::difficulty + random(1, 60 / Game::Game::difficulty)) class GVectorSprite : public BSprite { public: - GVectorSprite() : BSprite(0 , 0, ENull, STYPE_DEFAULT) { + GVectorSprite(TUint64 aType = STYPE_DEFAULT) : BSprite(0 , 0, ENull, aType) { mColor = COLOR_WHITE; mPad = 0; - mX = mY = mZ = 0; - mVX = mVY = mVZ = 0; - mFlags = mState = mTheta = 0; + x = y = z = 0; + vx = vy = vz = 0; + flags = mState = mTheta = 0; mTimer = 0; mLines = ENull; } @@ -42,27 +42,26 @@ class GVectorSprite : public BSprite { TBool Render(BViewPort *aViewPort) OVERRIDE; void Move() OVERRIDE { - mX += mVX; - mY += mVY; - mZ += mVZ; + x += vx; + y += vy; + z += vz; } // if lines is NULL, then the variables in the Object structure can be used // for any purpose const TInt8 *mLines; - TFloat mX, mY, mZ; // coordinates - TFloat mVX, mVY, mVZ; // velocity in x,y,z - TUint8 mFlags; - TInt8 mTimer; + TFloat z; // coordinates + TFloat vz; // velocity in x,y,z + TInt16 mTimer; TInt16 mState; // arbitrary data TInt8 for AI use (can be explosion step, etc.) TFloat mTheta; // rotation around Z (in degrees, 0-60) TUint8 mColor; TUint8 mPad; - inline void SetType(TUint8 aType) { - mFlags = (mFlags & ~OFLAG_TYPE_MASK) | aType; - } +// inline void SetType(TUint8 aType) { +// mFlags = (mFlags & ~OFLAG_TYPE_MASK) | aType; +// } TBool BehindCamera(); @@ -79,7 +78,7 @@ class GVectorSprite : public BSprite { } inline TUint8 Type() { - return mFlags & OFLAG_TYPE_MASK; + return flags & OFLAG_TYPE_MASK; } }; diff --git a/Evade2/src/img/ebomb_img.h b/Evade2/src/img/ebomb_img.h index c60a517..1fc4cc5 100644 --- a/Evade2/src/img/ebomb_img.h +++ b/Evade2/src/img/ebomb_img.h @@ -4,7 +4,7 @@ #include "BTypes.h" -const TInt16 ebomb_img[] = { +const TInt8 ebomb_img[] = { 16, // width 16, // height 9, // num rows diff --git a/Evade2/src/img/ebullet_img.h b/Evade2/src/img/ebullet_img.h index a58fba4..c1b3a37 100644 --- a/Evade2/src/img/ebullet_img.h +++ b/Evade2/src/img/ebullet_img.h @@ -3,7 +3,7 @@ #include "BTypes.h" -const TInt16 ebullet_img[] = { +const TInt8 ebullet_img[] = { 8, // width 8, // height 4, // num rows diff --git a/Evade2/src/main.cpp b/Evade2/src/main.cpp new file mode 100644 index 0000000..a447b5b --- /dev/null +++ b/Evade2/src/main.cpp @@ -0,0 +1,23 @@ +#include "Game.h" + +BViewPort *gViewPort; +BGameEngine *gGameEngine; + +GGame *gGame; +TOptions *gOptions; + +/** @file + * \brief Main entry point for game engine. + * + * Initializes the engine and runs the main event loop. + */ +extern "C" void app_main() { + gGame = new GGame(); + gGame->Run(); +} + +int main() { + app_main(); + return 0; +} + From c06eac5728770ce08949b449766a8dddbb3472ec Mon Sep 17 00:00:00 2001 From: Michael Schwartz Date: Tue, 3 Nov 2020 15:19:39 -0800 Subject: [PATCH 4/6] wip - plays --- Evade2/src/GResources.h | 4 +- Evade2/src/Game.h | 36 ++-- Evade2/src/GameState/GEnemyBulletProcess.cpp | 18 +- Evade2/src/GameState/GEnemyProcess.cpp | 65 +++---- Evade2/src/GameState/GGameState.h | 2 + Evade2/src/GameState/GPlayerBulletProcess.cpp | 17 +- Evade2/src/GameState/GPlayerProcess.cpp | 163 ++++++++++++------ Evade2/src/GameState/GPlayerProcess.h | 34 +++- Evade2/src/common/GVectorSprite.cpp | 33 +++- Evade2/src/common/GVectorSprite.h | 11 +- 10 files changed, 254 insertions(+), 129 deletions(-) diff --git a/Evade2/src/GResources.h b/Evade2/src/GResources.h index 3bbf60d..431723b 100644 --- a/Evade2/src/GResources.h +++ b/Evade2/src/GResources.h @@ -95,8 +95,7 @@ const TUint8 COLOR_BLACK = 0; const TUint8 COLOR_WHITE = 1; const TUint8 COLOR_TEXT = 2; const TUint8 COLOR_STAR = 3; -const TUint8 COLOR_ENEMY1 = 4; -const TUint8 COLOR_SHMOO = 255; +const TUint8 COLOR_HUD = 4; const TUint8 COLOR_BLUE = 201; const TUint8 COLOR_GREEN = 202; @@ -113,6 +112,7 @@ const TUint8 COLOR_BRIGHT_RED = 212; const TUint8 COLOR_BRIGHT_MAGENTA = 213; const TUint8 COLOR_YELLOW = 214; const TUint8 COLOR_SPACE = 215; +const TUint8 COLOR_SHMOO = 255; diff --git a/Evade2/src/Game.h b/Evade2/src/Game.h index ed227e0..2f4f11a 100644 --- a/Evade2/src/Game.h +++ b/Evade2/src/Game.h @@ -9,10 +9,13 @@ //#define SCREEN_HEIGHT 200 //#define SCREEN_DEPTH 8 -const TFloat CAMERA_VZ = 4; -const TFloat DELTACONTROL = 11; +const TFloat CAMERA_VZ = 2; // 4; +const TFloat DELTACONTROL = 6; // 11; const TInt8 MAX_BULLETS = 6; +const TFloat BULLET_VZ = 8; // 15; +// COLLISION_RADIUS = distance from player bullet to enemy required for a hit +const TFloat COLLISION_RADIUS = 64; #define BANK_LEFT TUint32(1<mDifficulty; - mSprite = new GVectorSprite(OTYPE_ENEMY_BULLET); - mSprite->mLines = (type == EBULLET_BOMB) ? ebomb_img : ebullet_img; + mSprite = new GVectorSprite(STYPE_EBULLET); + mSprite->SetLines( (type == EBULLET_BOMB) ? ebomb_img : ebullet_img); mSprite->mColor = (type == EBULLET_BOMB) ? BOMB_COLOR : EBULLET_COLOR; - mSprite->mTimer = 256 * 2; // timeout + mSprite->mTimer = 256; // timeout mSprite->x = enemy->x - 8; mSprite->y = enemy->y - 8; mSprite->z = enemy->z; @@ -30,17 +32,21 @@ GEnemyBulletProcess::~GEnemyBulletProcess() noexcept { } TBool GEnemyBulletProcess::RunBefore() { - mSprite->mTheta += (mSprite->mLines == ebomb_img) ? mSprite->x : 40; + mSprite->mTheta += (mSprite->GetLines() == ebomb_img) ? mSprite->x : 40; return ETrue; } TBool GEnemyBulletProcess::RunAfter() { + if (GCamera::CollidesWith(mSprite)) { + if (gGame->IsGameState()) { + gGameState->mPlayerProcess->Hit(10); + } + } + if (mSprite->BehindCamera()) { -// printf("RunAfter Behind\n"); return EFalse; } if (--mSprite->mTimer <= 0) { -// printf("RunAfter(%d) \n", mSprite->mTimer); return EFalse; } return ETrue; diff --git a/Evade2/src/GameState/GEnemyProcess.cpp b/Evade2/src/GameState/GEnemyProcess.cpp index de9e9a5..3670f7d 100644 --- a/Evade2/src/GameState/GEnemyProcess.cpp +++ b/Evade2/src/GameState/GEnemyProcess.cpp @@ -3,6 +3,7 @@ // #include "GGame.h" +#include "GGameState.h" #include "GEnemyProcess.h" #include "GEnemyBulletProcess.h" #include "GCamera.h" @@ -13,9 +14,9 @@ #define FIRE_TIME (60 / gGame->mDifficulty + Random(1, 60 / gGame->mDifficulty)) GEnemyProcess::GEnemyProcess() { - printf("Spawn GEmenyProcess\n"); - mSprite = new GVectorSprite(OTYPE_ENEMY); + mSprite = new GVectorSprite(STYPE_ENEMY); gGameEngine->AddSprite(mSprite); + mState = ESTATE_WAITINIT; respawn(); } @@ -52,7 +53,8 @@ void GEnemyProcess::fire() { } } -#define DELTA_THETA 8 +//#define DELTA_THETA 8 +#define DELTA_THETA 4 void GEnemyProcess::bank(TInt16 delta) { if (mSprite->flags & BANK_LEFT) { @@ -92,7 +94,7 @@ void GEnemyProcess::init_scout() { mSprite->x = GCamera::x + Random(-256, 256); mSprite->y = GCamera::y + Random(-256, 256); mSprite->z = GCamera::z + 1024; - mSprite->vz = CAMERA_VZ - 12; + mSprite->vz = CAMERA_VZ - 3; // 12; mSprite->vx = mSprite->vy = 0; mSprite->mTheta = Random(-50, 50); mSprite->mColor = SCOUT_COLOR; @@ -102,11 +104,11 @@ void GEnemyProcess::init_scout() { * Initialize object for bomber enemy */ void GEnemyProcess::init_bomber() { - mSprite->x = GCamera::x + 128 - Random(0, 127); - mSprite->y = GCamera::y + 128 - Random(0, 127); - mSprite->z = GCamera::z - 30; - mSprite->vz = CAMERA_VZ + 1 + gGame->mWave; - mSprite->vx = mSprite->vy = 0; + mSprite->x = GCamera::x + 128 - Random(0, 127); + mSprite->y = GCamera::y + 128 - Random(0, 127); + mSprite->z = GCamera::z - 30; + mSprite->vz = CAMERA_VZ + 1 + gGame->mWave; + mSprite->vx = mSprite->vy = 0; mSprite->mColor = BOMBER_COLOR; } @@ -119,22 +121,21 @@ void GEnemyProcess::init() { // One enemy type enters per wave switch (Random(0, (gGame->mWave > 3) ? 3 : gGame->mWave)) { case 0: - mSprite->mLines = (const TInt8 *) &enemy_scout_1_img; + mSprite->SetLines((const TInt8 *) &enemy_scout_1_img); init_scout(); mState = ESTATE_SEEK; break; case 1: - mSprite->mLines = (const TInt8 *) &enemy_heavy_bomber_1_img; + mSprite->SetLines((const TInt8 *) &enemy_heavy_bomber_1_img); init_bomber(); mState = ESTATE_EVADE; break; case 2: - mSprite->mLines = (const TInt8 *) &enemy_assault_1_img; + mSprite->SetLines((const TInt8 *) &enemy_assault_1_img); init_assault(Random() & 1); mState = ESTATE_ORBIT; break; } - printf("init\n"); } TBool GEnemyProcess::StateSeek() { @@ -191,26 +192,23 @@ TBool GEnemyProcess::StateOrbit() { if (o->mState < 0) { o->mState = 0; o->flags &= ~ORBIT_LEFT; - } - else { + } else { o->mTheta -= 12; } - } - else { + } else { o->mState += gGame->mDifficulty; if (o->mState > 180) { o->mState = 180; o->flags |= ORBIT_LEFT; - } - else { + } else { o->mTheta += 12; } } TFloat rad = RADIANS(o->mState); o->vy = (GCamera::y > o->y) ? -2 : 2; - o->y = GCamera::y; - o->x = cos(rad) * 256; + o->y = GCamera::y; + o->x = cos(rad) * 256; if (gGame->GetState() == GAME_STATE_GAME) { o->z = GCamera::z + sin(rad) * 256; } @@ -224,8 +222,7 @@ TBool GEnemyProcess::StateWaitInit() { if (o->mTimer <= 0 && gGame->GetState() == GAME_STATE_GAME) { init(); return ETrue; - } - else { + } else { o->mTimer = 1; } o->mTimer--; @@ -237,8 +234,7 @@ TBool GEnemyProcess::StateRunAway() { GVectorSprite *o = mSprite; if (gGame->GetState() != GAME_STATE_GAME) { o->vz += o->mState * 8; - } - else { + } else { o->vz += o->mState; } o->vx += o->vx > 0 ? .1 : -.1; @@ -268,10 +264,6 @@ TBool GEnemyProcess::StateExplode() { } TBool GEnemyProcess::RunBefore() { - return ETrue; -} - -TBool GEnemyProcess::RunAfter() { switch (mState) { case ESTATE_SEEK: return StateSeek(); @@ -288,4 +280,19 @@ TBool GEnemyProcess::RunAfter() { default: Panic("Bad Genemy State %d", mState); } + return ETrue; +} + +TBool GEnemyProcess::RunAfter() { +// BSpriteList &l = gGameState->mSpriteList; +// for (GVectorSprite *s = (GVectorSprite *)l.Prev(mSprite); !l.End(s); s = (GVectorSprite *) l.Prev(s)) { +// if (s->type & STYPE_PBULLET) { +// printf("%f %f %f %d/%d\n", ABS(mSprite->z - s->z), ABS(mSprite->y - s->y), ABS(mSprite->x - s->x), mSprite->w, mSprite->h); +// if (ABS(mSprite->z - s->z) < BULLET_VZ && ABS(mSprite->x - s->x) < mSprite->w && ABS(mSprite->y - s->y) < mSprite->h) { +// s->flags |= OFLAG_COLLISION; +// mSprite->flags |= OFLAG_COLLISION; +// } +// } +// } + return ETrue; } diff --git a/Evade2/src/GameState/GGameState.h b/Evade2/src/GameState/GGameState.h index 6b35827..c478509 100644 --- a/Evade2/src/GameState/GGameState.h +++ b/Evade2/src/GameState/GGameState.h @@ -12,7 +12,9 @@ class GPlayerProcess; class GGameState : public BGameEngine { public: GGameState(); + ~GGameState(); + public: // void GameLoop() OVERRIDE; GPlayerProcess *mPlayerProcess; diff --git a/Evade2/src/GameState/GPlayerBulletProcess.cpp b/Evade2/src/GameState/GPlayerBulletProcess.cpp index 26eab7b..9a9ca26 100644 --- a/Evade2/src/GameState/GPlayerBulletProcess.cpp +++ b/Evade2/src/GameState/GPlayerBulletProcess.cpp @@ -9,10 +9,8 @@ #include "img/bullet_img.h" -const TFloat BULLET_VZ = 15; - GPlayerBulletProcess::GPlayerBulletProcess(TFloat deltaX, TFloat deltaY, TBool alt) { - mSprite = new GVectorSprite(OTYPE_PLAYER_BULLET); + mSprite = new GVectorSprite(STYPE_PBULLET); if (alt) { mSprite->x = GCamera::x + 28; mSprite->y = GCamera::y - 28; @@ -27,12 +25,11 @@ GPlayerBulletProcess::GPlayerBulletProcess(TFloat deltaX, TFloat deltaY, TBool a mSprite->vx = deltaX; mSprite->vy = deltaY; mSprite->vz = GCamera::vz + BULLET_VZ; - mSprite->mLines = bullet_img; + mSprite->SetLines(bullet_img); gGameEngine->AddSprite(mSprite); } GPlayerBulletProcess::~GPlayerBulletProcess() noexcept { - printf("BUllet death\n"); gGameState->mPlayerProcess->mNumBullets--; mSprite->Remove(); delete mSprite; @@ -48,5 +45,15 @@ TBool GPlayerBulletProcess::RunAfter() { if (mSprite->z - GCamera::z > 512) { return EFalse; } + BSpriteList &l = gGameState->mSpriteList; + for (auto *s = (GVectorSprite *)l.First(); !l.End(s); s = (GVectorSprite *) l.Next(s)) { + if (s->type & (STYPE_EBULLET | STYPE_ENEMY)) { + TFloat d = mSprite->DistanceTo(s); + if (d < COLLISION_RADIUS) { + s->flags |= OFLAG_COLLISION; + mSprite->flags |= OFLAG_COLLISION; + } + } + } return ETrue; } \ No newline at end of file diff --git a/Evade2/src/GameState/GPlayerProcess.cpp b/Evade2/src/GameState/GPlayerProcess.cpp index a742e19..4c57505 100644 --- a/Evade2/src/GameState/GPlayerProcess.cpp +++ b/Evade2/src/GameState/GPlayerProcess.cpp @@ -25,25 +25,32 @@ const TUint8 crosshair_right_4x8[] = { #define MAX_LIFE 100 GPlayerProcess::GPlayerProcess() { - color = COLOR_WHITE; + color = COLOR_WHITE; GCamera::vz = CAMERA_VZ; - power = MAX_POWER; - shield = MAX_LIFE; - mNumBullets = 0; - mAlt = EFalse; - mHit = EFalse; + power = MAX_POWER; + shield = MAX_LIFE; + mNumBullets = 0; + mAlt = EFalse; + mHit = EFalse; printf("screen %d,%d\n", gDisplay.renderBitmap->Width(), gDisplay.renderBitmap->Height()); } -void GPlayerProcess::DrawPixel(TFloat x, TFloat y) { +void GPlayerProcess::DrawPixel(TFloat x, TFloat y) const { gDisplay.renderBitmap->WritePixel(x, y, color); } -void GPlayerProcess::DrawLine(TFloat x1, TFloat y1, TFloat x2, TFloat y2) { +void GPlayerProcess::DrawPixel(TFloat x, TFloat y, TUint8 aColor) { + gDisplay.renderBitmap->WritePixel(x, y, aColor); +} + +void GPlayerProcess::DrawLine(TFloat x1, TFloat y1, TFloat x2, TFloat y2) const { gDisplay.renderBitmap->DrawLine(gViewPort, x1, y1, x2, y2, color); } -void GPlayerProcess::DrawBitmap(TInt16 x, TInt16 y, const TUint8 *bitmap, TUint8 w, TUint8 h, TUint8 color) { +void GPlayerProcess::DrawBitmap(TInt16 x, TInt16 y, const TUint8 *bitmap, TUint8 w, TUint8 h, TUint8 aColor) const { + if (x + w < 0 || x > SCREEN_WIDTH - 1 || y + h < 0 || y > SCREEN_HEIGHT - 1) { + return; + } #if 0 // no need to draw at all if we're offscreen if (x + w < 0 || x > WIDTH - 1 || y + h < 0 || y > HEIGHT - 1) @@ -92,7 +99,7 @@ void GPlayerProcess::DrawBitmap(TInt16 x, TInt16 y, const TUint8 *bitmap, TUint8 #endif } -void GPlayerProcess::hit(TInt8 amount) { +void GPlayerProcess::Hit(TInt8 amount) { shield -= amount; if (shield <= 0) { // ProcessManager::birth(GameOver::entry); @@ -180,10 +187,35 @@ TBool GPlayerProcess::RunBefore() { /** HUD */ /************************************************************************/ +void GPlayerProcess::DrawHud(TFloat x, TFloat y) { + + const TUint8 color = COLOR_WHITE; + const TFloat width = 0x30, height = 0x08; + const TUint8 *bitmap = hud_console_img; + + for (TInt xx = 0, xxx = 0; xx < width; xx++, xxx += 2) { + for (TInt yy = 0, yyy = 0; yy < height; yy++, yyy += 2) { + if (y + yy > SCREEN_HEIGHT-1) { + continue; + } + TInt8 byte = bitmap[xx + (yy / 8)]; + TInt8 bit = (yy % 8); + if (byte & (1 << bit)) { + // Graphics::drawPixel(x + xx, y + yy, color); + DrawPixel(x + xxx, y + yyy, COLOR_HUD); + DrawPixel(x + xxx + 1, y + yyy, COLOR_HUD); + DrawPixel(x + xxx, y + yyy + 1, COLOR_HUD); + DrawPixel(x + xxx + 1, y + yyy + 1, COLOR_HUD); + // Graphics::drawPixel(x + xx * 2 + 1, y + yy * 2 + 1, color); + } + } + } +} + #ifdef ENABLE_HUD_MOVEMENTS // 13 == full. Anything less, and we draw "less meter" -void DrawMeter(TInt8 side, TInt8 value, TInt8 deltaXMeter, TInt8 deltaYMeter) { +void GPlayerProcess::DrawMeter(TInt8 side, TInt8 value, TInt8 deltaXMeter, TInt8 deltaYMeter) { //start at X:14 // Draw 2 lines, skip one line, iterate 13 total times @@ -198,26 +230,25 @@ void DrawMeter(TInt8 side, TInt8 value, TInt8 deltaXMeter, TInt8 deltaYMeter) { if (i >= value) { DrawPixel(1 + deltaXMeter, y + deltaYMeter); DrawPixel(1 + deltaXMeter, y + 1 + deltaYMeter); - } - else { + } else { DrawLine(1 + deltaXMeter, y + deltaYMeter, 3 + deltaXMeter, y + deltaYMeter); DrawLine(1 + deltaXMeter, y + 1 + deltaYMeter, 4 + deltaXMeter, y + 1 + deltaYMeter); } y -= 3; } - } - else { // RIGHT - for (TInt8 i = 0; i < 10; i++) { + } else { // RIGHT + const TInt RIGHT_SIDE = SCREEN_WIDTH - 2; + for (TInt8 i = 0; i < 10; i++) { if (i >= value) { - DrawPixel(126 + deltaXMeter, y + deltaYMeter); - DrawPixel(126 + deltaXMeter, y + 1 + deltaYMeter); - } - else { - DrawLine(124 + deltaXMeter, y + deltaYMeter, 126 + deltaXMeter, y + deltaYMeter); - DrawLine(123 + deltaXMeter, y + 1 + deltaYMeter, 126 + deltaXMeter, y + 1 + deltaYMeter); + DrawPixel(RIGHT_SIDE + deltaXMeter, y + deltaYMeter); + DrawPixel(RIGHT_SIDE + deltaXMeter, y + 1 + deltaYMeter); + } else { + DrawLine(RIGHT_SIDE - 2 + deltaXMeter, y + deltaYMeter, RIGHT_SIDE + deltaXMeter, y + deltaYMeter); + DrawLine(RIGHT_SIDE - 3 + deltaXMeter, y + 1 + deltaYMeter, RIGHT_SIDE + deltaXMeter, y + 1 + deltaYMeter); } y -= 3; } + } } @@ -270,47 +301,73 @@ TBool GPlayerProcess::RunAfter() { mHit = EFalse; #ifdef ENABLE_HUD_MOVEMENTS - TInt8 consoleX = 40, - consoleY = 58, - deltaXMeter = 0, - deltaYMeter = 0, - deltaXCrossHairs = 0, - deltaYCrossHairs = 0; - - // Font::scale = .6 * 256; - // Font::printf(5,5,"D %d", Game::difficulty); - // Font::printf(5,12,"W %d", Game::wave); - // Font::scale = 256; - if (game_mode == MODE_GAME) { - - if (gControls.IsPressed(JOYSTICK_RIGHT)) { - consoleX = 38; - deltaXMeter = -1; + TFloat consoleX = 0, consoleY = 0, deltaXMeter = 0, deltaYMeter = 0, + deltaXCrossHairs = 0, deltaYCrossHairs = 0; + + + if (gGame->IsGameState()) { + + if (gControls.IsPressed(CONTROL_JOYRIGHT)) { + consoleX = -4; + deltaXMeter = -1; deltaXCrossHairs = 4; - } - else if (gControls.IsPressed(JOYSTICK_LEFT)) { - consoleX = 42; - deltaXMeter = 1; + } else if (gControls.IsPressed(CONTROL_JOYLEFT)) { + consoleX = 4; + deltaXMeter = 1; deltaXCrossHairs = -4; } - if (gControls.IsPressed(JOYSTICK_UP)) { - consoleY = 56; - deltaYMeter = -1; + if (gControls.IsPressed(CONTROL_JOYUP)) { + consoleY = -4; + deltaYMeter = -1; deltaYCrossHairs = 4; - } - else if (gControls.IsPressed(JOYSTICK_DOWN)) { - consoleY = 60; - deltaYMeter = 1; + } else if (gControls.IsPressed(CONTROL_JOYDOWN)) { + consoleY = 4; + deltaYMeter = 1; deltaYCrossHairs = -4; } } - DrawBitmap(consoleX, consoleY, hud_console_img, 0x30, 0x08); - // // DrawLine(64, 0, 64, 64); // used to measure the center of the screen. + const TFloat screenMidX = TFloat(SCREEN_WIDTH)/2, screenMidY = TFloat(SCREEN_HEIGHT)/2; + + DrawHud(screenMidX - (0x30) + consoleX, (240 + consoleY) - 12); + + /** Reticle **/ + // Top left + DrawLine(screenMidX + deltaXCrossHairs - 5, + screenMidY + deltaYCrossHairs, + screenMidX + deltaXCrossHairs - 12, + screenMidY + deltaYCrossHairs - 7); + + DrawPixel(screenMidX + deltaXCrossHairs - 5, + screenMidY + deltaYCrossHairs - 5, 255); + + // Top Right + DrawLine(screenMidX + deltaXCrossHairs + 5, + screenMidY + deltaYCrossHairs, + screenMidX + deltaXCrossHairs + 12, + screenMidY + deltaYCrossHairs - 7); + + DrawPixel(screenMidX + deltaXCrossHairs + 5, + screenMidY + deltaYCrossHairs - 5, 255); + + // Bottom Right + DrawLine(screenMidX + deltaXCrossHairs + 5, + screenMidY + deltaYCrossHairs, + screenMidX + deltaXCrossHairs + 12, + screenMidY + deltaYCrossHairs + 7); + + DrawPixel(screenMidX + deltaXCrossHairs + 5, + screenMidY + deltaYCrossHairs + 5, 255); + + // Bottom left + DrawLine(screenMidX + deltaXCrossHairs - 5, + screenMidY + deltaYCrossHairs, + screenMidX + deltaXCrossHairs - 12, + screenMidY + deltaYCrossHairs + 7); - DrawBitmap(53 + deltaXCrossHairs, 30 + deltaYCrossHairs, crosshair_left_4x8, 4, 8); - DrawBitmap(72 + deltaXCrossHairs, 30 + deltaYCrossHairs, crosshair_right_4x8, 4, 8); + DrawPixel(screenMidX + deltaXCrossHairs - 5, + screenMidY + deltaYCrossHairs + 5, 255); DrawMeter(0, shield, deltaXMeter, deltaYMeter); DrawMeter(1, power, deltaXMeter, deltaYMeter); diff --git a/Evade2/src/GameState/GPlayerProcess.h b/Evade2/src/GameState/GPlayerProcess.h index a1a7433..eb48be0 100644 --- a/Evade2/src/GameState/GPlayerProcess.h +++ b/Evade2/src/GameState/GPlayerProcess.h @@ -13,28 +13,44 @@ class GPlayerProcess : public BProcess { GPlayerProcess(); public: - TInt8 power; - TInt8 shield; - TInt8 mNumBullets; + TInt8 power; + TInt8 shield; + TInt8 mNumBullets; // TUint8 flags; TUint8 color; - TBool mAlt; - TBool mHit; + TBool mAlt; + TBool mHit; public: void recharge_shield(); + void recharge_power(); - void hit(TInt8 amount); - void DrawPixel(TFloat x, TFloat y); - void DrawLine(TFloat x1, TFloat y1, TFloat x2, TFloat y2); + void Hit(TInt8 amount); + + void DrawPixel(TFloat x, TFloat y) const; + + void DrawPixel(TFloat x, TFloat y, TUint8 aColor); + + void DrawLine(TFloat x1, TFloat y1, TFloat x2, TFloat y2) const; protected: +#ifdef ENABLE_HUD_MOVEMENTS + + void DrawHud(TFloat x, TFloat y); + + void DrawMeter(TInt8 side, TInt8 value, TInt8 deltaXMeter, TInt8 deltaYMeter); + +#else + } void DrawMeter(TInt8 side, TInt8 value); - void DrawBitmap(TInt16 x, TInt16 y, const TUint8 *bitmap, TUint8 w, TUint8 h, TUint8 color = COLOR_WHITE); +#endif + + void DrawBitmap(TInt16 x, TInt16 y, const TUint8 *bitmap, TUint8 w, TUint8 h, TUint8 aColor = COLOR_WHITE) const; public: TBool RunBefore() OVERRIDE; + TBool RunAfter() OVERRIDE; }; diff --git a/Evade2/src/common/GVectorSprite.cpp b/Evade2/src/common/GVectorSprite.cpp index bce0577..d0f9f7b 100644 --- a/Evade2/src/common/GVectorSprite.cpp +++ b/Evade2/src/common/GVectorSprite.cpp @@ -1,6 +1,12 @@ #include "GVectorSprite.h" #include "GameState/GCamera.h" +void GVectorSprite::SetLines(const TInt8 *aLines) { + mLines = aLines; + auto *p = (const TUint16 *) mLines; + w = p[0]; + h = p[1]; +} TBool GVectorSprite::ExplodeVectorGraphic(const TInt8 *graphic, TFloat x, TFloat y, TFloat theta, TFloat scaleFactor, TInt8 step, TUint8 color) { @@ -63,6 +69,14 @@ TBool GVectorSprite::ExplodeVectorGraphic(const TInt8 *graphic, TFloat x, TFloat return drawn; } +static TFloat square(TFloat f) { + return f * f; +} + +TFloat GVectorSprite::DistanceTo(GVectorSprite *aOther) { + return sqrt(square(aOther->x - x) + square(aOther->y - y) + square(aOther->z - z)); +}; + TBool GVectorSprite::Render(BViewPort *aViewPort) { if (!mLines || z <= GCamera::z) { // nothing to draw @@ -74,7 +88,7 @@ TBool GVectorSprite::Render(BViewPort *aViewPort) { TFloat sw = TFloat(SCREEN_WIDTH), sh = TFloat(SCREEN_HEIGHT); - bool isEnemy = Type() == OTYPE_ENEMY; + bool isEnemy = type == STYPE_ENEMY; // printf("is enemy = %i\n", isEnemy); TFloat cx = (GCamera::x - x) * ratio + sw / 2; TFloat cy = (GCamera::y - y) * ratio + sh / 2; @@ -90,14 +104,21 @@ TBool GVectorSprite::Render(BViewPort *aViewPort) { // draw radar blip TFloat dx = GCamera::x - x, dy = GCamera::y - y, - angle = atan2(dy, dx); + angle = atan2(dy, dx), + midx = sw / 2, + midy = sh / 2, + cxx = midx + cos(angle) * (midx - 10), + cyy = midy + sin(angle) * (midy - 10); // printf("TODO: Fill Circle for enemy radar\n"); + +// printf("Angle: %f, x: %f, y: %f, cx,cy: %f,%f\n", angle, x, y, cx, cy); aViewPort->FillCircle(gDisplay.renderBitmap, - (int16_t) (sw / 2 + cos(angle) * 75), - (int16_t) (sh / 2 + sin(angle) * 75), - 3, - mColor + (TInt16) cxx, + (TInt16) cyy, + 4, + COLOR_SHMOO +// mColor ); } diff --git a/Evade2/src/common/GVectorSprite.h b/Evade2/src/common/GVectorSprite.h index cfacbb0..8d8930d 100644 --- a/Evade2/src/common/GVectorSprite.h +++ b/Evade2/src/common/GVectorSprite.h @@ -46,11 +46,17 @@ class GVectorSprite : public BSprite { y += vy; z += vz; } +public: + void SetLines(const TInt8 *aLines); + const TInt8 *GetLines() { return mLines; } +protected: // if lines is NULL, then the variables in the Object structure can be used // for any purpose const TInt8 *mLines; +public: + TFloat z; // coordinates TFloat vz; // velocity in x,y,z TInt16 mTimer; @@ -64,6 +70,7 @@ class GVectorSprite : public BSprite { // } TBool BehindCamera(); + TFloat DistanceTo(GVectorSprite *aOther); TBool do_death() { // if (o->flags & OFLAG_COLLISION) { @@ -76,10 +83,6 @@ class GVectorSprite : public BSprite { // } return EFalse; } - - inline TUint8 Type() { - return flags & OFLAG_TYPE_MASK; - } }; From 1a5c6aaf95f0fe20b1e3239b132d22833567990b Mon Sep 17 00:00:00 2001 From: Michael Schwartz Date: Wed, 4 Nov 2020 14:17:17 -0800 Subject: [PATCH 5/6] splash, attract, credits implemented and working ok. Needs start game/title screen. --- Evade2/CMakeLists.txt | 6 +- Evade2/old/GameState/enemies/GBossSprite.cpp | 2 +- Evade2/old/GameState/enemies/GEnemySprite.cpp | 2 +- .../old/GameState/player/GPlayerProcess.cpp | 2 +- Evade2/old/SplashState/Splash.cpp | 66 ----- Evade2/old/SplashState/Splash.h | 20 -- Evade2/src/AttractState/GAttractProcess.cpp | 226 +++++++++++++++++ Evade2/src/AttractState/GAttractProcess.h | 45 ++++ Evade2/src/AttractState/GAttractState.cpp | 34 +++ Evade2/src/AttractState/GAttractState.h | 18 ++ Evade2/src/GGame.cpp | 228 ++++-------------- Evade2/src/GGame.h | 37 ++- Evade2/src/GResources.h | 6 +- Evade2/src/Game.h | 2 +- Evade2/src/GameState/GEnemyProcess.cpp | 21 +- Evade2/src/GameState/GEnemyProcess.h | 24 +- Evade2/src/GameState/GGameState.cpp | 4 +- Evade2/src/MainMenuState/GMainMenu.cpp | 12 + Evade2/src/MainMenuState/GMainMenu.h | 18 ++ Evade2/src/MainMenuState/GMainMenuProcess.cpp | 5 + Evade2/src/MainMenuState/GMainMenuProcess.h | 24 ++ .../SplashState/GSplashPlayfield.cpp | 0 .../SplashState/GSplashPlayfield.h | 0 .../SplashState/GSplashProcess.cpp | 10 +- .../{old => src}/SplashState/GSplashProcess.h | 0 .../{old => src}/SplashState/GSplashState.cpp | 7 +- .../{old => src}/SplashState/GSplashState.h | 2 +- Evade2/src/{GameState => common}/GCamera.cpp | 0 Evade2/src/{GameState => common}/GCamera.h | 0 .../GStarfield.cpp} | 10 +- .../GGamePlayfield.h => common/GStarfield.h} | 12 +- Evade2/src/common/GVectorFont.cpp | 224 +++-------------- Evade2/src/common/GVectorFont.h | 16 +- Evade2/src/common/GVectorSprite.cpp | 2 +- Evade2/src/common/GVectorSprite.h | 10 +- Evade2/src/common/charset.h | 160 ++++++++++++ Evade2/src/img/README.md | 4 + 37 files changed, 727 insertions(+), 532 deletions(-) delete mode 100644 Evade2/old/SplashState/Splash.cpp delete mode 100644 Evade2/old/SplashState/Splash.h create mode 100644 Evade2/src/AttractState/GAttractProcess.cpp create mode 100644 Evade2/src/AttractState/GAttractProcess.h create mode 100644 Evade2/src/AttractState/GAttractState.cpp create mode 100644 Evade2/src/AttractState/GAttractState.h create mode 100644 Evade2/src/MainMenuState/GMainMenu.cpp create mode 100644 Evade2/src/MainMenuState/GMainMenu.h create mode 100644 Evade2/src/MainMenuState/GMainMenuProcess.cpp create mode 100644 Evade2/src/MainMenuState/GMainMenuProcess.h rename Evade2/{old => src}/SplashState/GSplashPlayfield.cpp (100%) rename Evade2/{old => src}/SplashState/GSplashPlayfield.h (100%) rename Evade2/{old => src}/SplashState/GSplashProcess.cpp (91%) rename Evade2/{old => src}/SplashState/GSplashProcess.h (100%) rename Evade2/{old => src}/SplashState/GSplashState.cpp (62%) rename Evade2/{old => src}/SplashState/GSplashState.h (86%) rename Evade2/src/{GameState => common}/GCamera.cpp (100%) rename Evade2/src/{GameState => common}/GCamera.h (100%) rename Evade2/src/{GameState/GGamePlayfield.cpp => common/GStarfield.cpp} (86%) rename Evade2/src/{GameState/GGamePlayfield.h => common/GStarfield.h} (60%) create mode 100644 Evade2/src/img/README.md diff --git a/Evade2/CMakeLists.txt b/Evade2/CMakeLists.txt index 85a8524..af1169f 100644 --- a/Evade2/CMakeLists.txt +++ b/Evade2/CMakeLists.txt @@ -29,7 +29,7 @@ SET(EVADE2_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/resources ${CMAKE_SOURCE_DIR}/src/common # ${CMAKE_SOURCE_DIR}/src/LoadGameState -# ${CMAKE_SOURCE_DIR}/src/GameState + ${CMAKE_SOURCE_DIR}/src/GameState # ${CMAKE_SOURCE_DIR}/src/GameState/environment # ${CMAKE_SOURCE_DIR}/src/GameState/player # ${CMAKE_SOURCE_DIR}/src/GameState/inventory @@ -46,7 +46,7 @@ SET(EVADE2_INCLUDE_DIRS # ${CMAKE_SOURCE_DIR}/src/VictoryState # ${CMAKE_SOURCE_DIR}/src/MainMenuState # ${CMAKE_SOURCE_DIR}/src/MainOptionsState -# ${CMAKE_SOURCE_DIR}/src/SplashState + ${CMAKE_SOURCE_DIR}/src/SplashState # ${CMAKE_SOURCE_DIR}/src/CreditsState # ${CMAKE_SOURCE_DIR}/src/ResetState ${CMAKE_BINARY_DIR}/usr/local/include @@ -65,7 +65,7 @@ ADD_EXECUTABLE( Resources.bin ${CREATIVE_ENGINE_SOURCE_FILES} ${EVADE2_SRC} - src/GameState/GGameState.cpp src/GameState/GGameState.h src/GameState/GGamePlayfield.cpp src/GameState/GGamePlayfield.h src/GameState/GPlayerBulletProcess.cpp src/GameState/GPlayerBulletProcess.h src/main.cpp src/GameState/GEnemyProcess.cpp src/GameState/GEnemyProcess.h src/GameState/GEnemyBulletProcess.cpp src/GameState/GEnemyBulletProcess.h) + src/GameState/GGameState.cpp src/GameState/GGameState.h src/common/GStarfield.cpp src/common/GStarfield.h src/GameState/GPlayerBulletProcess.cpp src/GameState/GPlayerBulletProcess.h src/main.cpp src/GameState/GEnemyProcess.cpp src/GameState/GEnemyProcess.h src/GameState/GEnemyBulletProcess.cpp src/GameState/GEnemyBulletProcess.h src/AttractState/GAttractState.cpp src/AttractState/GAttractState.h src/AttractState/GAttractProcess.cpp src/AttractState/GAttractProcess.h src/MainMenuState/GMainMenu.cpp src/MainMenuState/GMainMenu.h src/MainMenuState/GMainMenuProcess.cpp src/MainMenuState/GMainMenuProcess.h) ProcessorCount(N) if (NOT N EQUAL 0) diff --git a/Evade2/old/GameState/enemies/GBossSprite.cpp b/Evade2/old/GameState/enemies/GBossSprite.cpp index 280171e..55f2be8 100644 --- a/Evade2/old/GameState/enemies/GBossSprite.cpp +++ b/Evade2/old/GameState/enemies/GBossSprite.cpp @@ -2,7 +2,7 @@ #include "GResources.h" #include "GBossSprite.h" #include "GPlayer.h" -#include "GameState/GCamera.h" +#include "common/GCamera.h" static const TFloat z_dist = 256; static const TFloat frames = 32; diff --git a/Evade2/old/GameState/enemies/GEnemySprite.cpp b/Evade2/old/GameState/enemies/GEnemySprite.cpp index 5648c71..265d4e9 100644 --- a/Evade2/old/GameState/enemies/GEnemySprite.cpp +++ b/Evade2/old/GameState/enemies/GEnemySprite.cpp @@ -2,7 +2,7 @@ #include "GResources.h" #include "GEnemySprite.h" #include "GPlayer.h" -#include "GameState/GCamera.h" +#include "common/GCamera.h" const TInt8 *enemy_graphic(TInt16 n) { diff --git a/Evade2/old/GameState/player/GPlayerProcess.cpp b/Evade2/old/GameState/player/GPlayerProcess.cpp index 09cdb61..b897b60 100644 --- a/Evade2/old/GameState/player/GPlayerProcess.cpp +++ b/Evade2/old/GameState/player/GPlayerProcess.cpp @@ -1,7 +1,7 @@ #include "GPlayerProcess.h" #include "GPlayer.h" #include "GPlayerSprite.h" -#include "GGamePlayfield.h" +#include "GStarfield.h" #include "GStatProcess.h" #include "GResources.h" #include "GPlayerBulletProcess.h" diff --git a/Evade2/old/SplashState/Splash.cpp b/Evade2/old/SplashState/Splash.cpp deleted file mode 100644 index e0b04ef..0000000 --- a/Evade2/old/SplashState/Splash.cpp +++ /dev/null @@ -1,66 +0,0 @@ -//#define DEBUGME -////#undef DEBUGME -// -//#include "Evade2.h" -// -//BOOL Splash::attract_mode = TRUE; -// -//struct splash_data { -//#ifdef ENABLE_ROTATING_TEXT -// FLOAT theta; // angle of rotating text -//#endif -// WORD timer; -//}; -// -///** -// * Wait for the human to press the A button -// */ -//void Splash::wait(Process *me, Object *o) { -// splash_data *d = (splash_data *)&o->x; -// -// Font::scale = 2 * 0x200; -//#ifdef ENABLE_ROTATING_TEXT -// Font::print_string_rotatedx(SHMOO_COLOR, 60, 90, d->theta, "EVADE 2"); -// d->theta += 10; -// if (d->theta > 90 + 360 * 2) { -// d->theta = 90 + 360 * 2; -// } -//#else -// Font::printf(SHMOO_COLOR, 60, 90, "EVADE 2"); -//#endif -// Font::scale = 0x100; -// -// d->timer--; -// if (d->timer < 0 || Controls::debounced(BUTTON_START)) { -// game_mode = attract_mode ? MODE_ATTRACT : MODE_CREDITS; -// attract_mode = !attract_mode; -// ProcessManager::birth(Attract::entry); -// me->suicide(); -// return; -// } -// if (d->timer & 16) { -// Font::scale = 0x200; -// Font::printf(SHMOO_COLOR, 130, 155, "START"); -// } -// -// if (Controls::debounced(BUTTON_A) || Controls::debounced(BUTTON_B)) { -// ProcessManager::birth(Game::entry); -// me->suicide(); -// return; -// } -// me->sleep(1); -//} -// -//void Splash::entry(Process *me, Object *o) { -// splash_data *d = (splash_data *)&o->x; -// -// game_mode = MODE_SPLASH; -//#ifdef ENABLE_ROTATING_TEXT -// d->theta = 90; -//#endif -// d->timer = 240; -// -// Camera::vz = CAMERA_VZ; -// Sound::play_score(INTRO_SONG); -// me->sleep(1, Splash::wait); -//} diff --git a/Evade2/old/SplashState/Splash.h b/Evade2/old/SplashState/Splash.h deleted file mode 100644 index d9a5148..0000000 --- a/Evade2/old/SplashState/Splash.h +++ /dev/null @@ -1,20 +0,0 @@ -//#ifndef SPLASH_H -//#define SPLASH_H -// -//#include "Evade2.h" -// -//class Splash { -//private: -// static BOOL attract_mode; -// -//private: -// // states -// static void show_logo(Process *me); -// static void wait(Process *me, Object *o); -// -//public: -// // initial state -// static void entry(Process *me, Object *o); -//}; -// -//#endif diff --git a/Evade2/src/AttractState/GAttractProcess.cpp b/Evade2/src/AttractState/GAttractProcess.cpp new file mode 100644 index 0000000..6bd5b5e --- /dev/null +++ b/Evade2/src/AttractState/GAttractProcess.cpp @@ -0,0 +1,226 @@ +// +// Created by Michael Schwartz on 11/4/20. +// + +#include "GAttractProcess.h" +#include "GEnemyProcess.h" + + +static const TInt8 TYPEWRITER_SPEED = 10; +static const TInt8 LINE_HEIGHT = 26; + +static const char scout_text[] = "SCOUT"; +static const char bomber_text[] = "BOMBER"; +static const char assault_text[] = "ASSAULT"; + +static const char credits1[] = "CRAFTED BY:\nMODUS CREATE\nDECEMBER 2017"; +static const char credits2[] = "MUSIC and SFX:\nJ. GARCIA"; +static const char credits3[] = + "ART:\nM. TINTIUC\nJV DALEN\nJD JONES\nJ. GARCIA"; +static const char credits4[] = + "PROGRAMMING:\nM. SCHWARTZ\nJ. GARCIA\nM. TINTIUC\n"; +static const char credits5[] = + "PROGRAMMING:\nD. BRIGNOLI\nS. LEMMONS\nA. DENNIS"; +static const char credits6[] = "PROGRAMMING:\nV. POPA\nL. STILL\nG. GRISOGONO"; + +const TInt8 MAX_SCREEN = 2; +const TInt8 MAX_CREDITS = 5; + +enum { + STATE_TYPEWRITER, + STATE_NEXT, +}; + +GAttractProcess::GAttractProcess() : BProcess() { +// mSprite = new GVectorSprite(); +// gGameEngine->AddSprite(mSprite); + auto *ad = (TAttractData *) &mData; + ad->screen = 0; + InitScreen(); +// Sound::play_sound(SFX_NEXT_ATTRACT_SCREEN); + mState = STATE_TYPEWRITER; +} + +GAttractProcess::~GAttractProcess() { + // +} + +TBool GAttractProcess::RunBefore() { + return ETrue; +} + +TBool GAttractProcess::RunAfter() { + switch (mState) { + case STATE_TYPEWRITER: + return TypewriterState(); + case STATE_NEXT: + return NextState(); + default: + Panic("invalid state: mState(%d)", mState); + } + + return ETrue; +} + +void GAttractProcess::InitScreen(TInt16 x, TInt16 y) { + auto *ad = &mData; + if (gGame->GetState() == GAME_STATE_ATTRACT_MODE) { + switch (ad->screen) { + case 0: + ad->enemy = ENEMY_SCOUT; + ad->text = scout_text; + x = 125; + y = 60; + break; + case 1: + ad->enemy = ENEMY_BOMBER; + ad->text = bomber_text; + x = 117; + y = 60; + break; + case 2: + ad->enemy = ENEMY_ASSAULT; + ad->text = assault_text; + x = 110; + y = 60; + break; + } + } else { + ad->enemy = -1; + switch (ad->screen) { + case 0: + ad->text = credits1; + break; + case 1: + ad->text = credits2; + break; + case 2: + ad->text = credits3; + break; + case 3: + ad->text = credits4; + break; + case 4: + ad->text = credits5; + break; + case 5: + ad->text = credits6; + break; + } + } + + ad->offset = 1; + ad->x = x; + ad->y = y; + ad->timer = TYPEWRITER_SPEED; + ad->done = EFalse; +} + +TBool GAttractProcess::NextState() { + auto *ad = (TAttractData *) &mData; + TInt game_mode = gGame->GetState(); + + ad->timer--; + if (ad->timer < 0) { + ad->screen++; + if ((game_mode == GAME_STATE_ATTRACT_MODE && ad->screen > MAX_SCREEN) || + (game_mode == GAME_STATE_CREDITS && ad->screen > MAX_CREDITS)) { + gGame->SetState(GAME_STATE_CREDITS); + return EFalse; + } else { +// Sound::play_sound(SFX_NEXT_ATTRACT_SCREEN); + InitScreen(); + mState = STATE_TYPEWRITER; + return ETrue; + } + } else { + return ETrue; + } +} + +TBool GAttractProcess::TypewriterState() { + auto *ad = (TAttractData *) &mData; + TInt game_mode = gGame->GetState(); + + ad->timer--; + + if (gControls.WasPressed(CONTROL_FIRE)) { + gGame->SetState(GAME_STATE_GAME); + return EFalse; + } + if (gControls.WasPressed(BUTTON_START)) { + ad->timer = -1; +// me->sleep(1, next); + return EFalse; + } + + if (ad->timer < 0) { + if (ad->done) { + ad->timer = 50; +// me->sleep(1, next); + mState = STATE_NEXT; + return ETrue; + } + ad->timer = TYPEWRITER_SPEED; + ad->offset++; +// Sound::play_sound(SFX_NEXT_ATTRACT_CHAR); + } + + switch (ad->enemy) { + case ENEMY_ASSAULT: + GVectorSprite::DrawVectorGraphic(GEnemyProcess::Graphic(ad->enemy), + TFloat(SCREEN_WIDTH) / 2, TFloat(SCREEN_HEIGHT) / 2, 0.0, + .75, // Originally 2.0 + ASSAULT_COLOR); + break; + case ENEMY_BOMBER: + GVectorSprite::DrawVectorGraphic(GEnemyProcess::Graphic(ad->enemy), + TFloat(SCREEN_WIDTH) / 2, TFloat(SCREEN_HEIGHT) / 2, 0.0, + .75, // Originally 2.0 + BOMBER_COLOR); + break; + case ENEMY_SCOUT: + GVectorSprite::DrawVectorGraphic(GEnemyProcess::Graphic(ad->enemy), + TFloat(SCREEN_WIDTH) / 2, TFloat(SCREEN_HEIGHT) / 2, 0.0, + .75, // Originally 2.0 + SCOUT_COLOR); + break; + } + if (game_mode == GAME_STATE_CREDITS) { + gVectorFont->scale = 2.0; + } + + const char *p = ad->text; + TInt16 x = ad->x, + y = ad->y; + + for (TInt8 i = 0; i < ad->offset;) { + char c = *p++; + if (c == '\0') { + if (!ad->done) { + ad->timer = 60; // 2 seconds + ad->done = ETrue; + } + break; + } else if (c == '\n') { + x = 20; + y += LINE_HEIGHT; + } else { + x += gVectorFont->write(x, y, c); + i++; + } + } + // if (game_mode == MODE_CREDITS) { + gVectorFont->scale = 2; + // } + return ETrue; +} + +//void Attract::entry() { +// TAttractData *ad = (TAttractData *) &mData; +// ad->screen = 0; +// InitScreen(); +// Sound::play_sound(SFX_NEXT_ATTRACT_SCREEN); +// +// me->sleep(1, typewriter); +//} diff --git a/Evade2/src/AttractState/GAttractProcess.h b/Evade2/src/AttractState/GAttractProcess.h new file mode 100644 index 0000000..31865a4 --- /dev/null +++ b/Evade2/src/AttractState/GAttractProcess.h @@ -0,0 +1,45 @@ +// +// Created by Michael Schwartz on 11/4/20. +// + +#ifndef EVADE2_GATTRACTPROCESS_H +#define EVADE2_GATTRACTPROCESS_H + +#include "Game.h" +#include "GVectorSprite.h" + +struct TAttractData { + TInt8 screen; + TInt8 x; + TInt8 y; + TInt8 offset; + TInt16 timer; + TBool done; + const char *text; + TInt8 enemy; +}; + +class GAttractProcess : public BProcess { +public: + GAttractProcess(); + + ~GAttractProcess(); + +public: + TBool RunBefore() OVERRIDE; + + TBool RunAfter() OVERRIDE; + +protected: + void InitScreen(TInt16 x = 20, TInt16 y = 30) ; + TBool NextState(); + TBool TypewriterState(); + +protected: + TInt mState; + TAttractData mData; + GVectorSprite *mSprite; +}; + + +#endif //EVADE2_GATTRACTPROCESS_H diff --git a/Evade2/src/AttractState/GAttractState.cpp b/Evade2/src/AttractState/GAttractState.cpp new file mode 100644 index 0000000..d892685 --- /dev/null +++ b/Evade2/src/AttractState/GAttractState.cpp @@ -0,0 +1,34 @@ +// +// Created by Michael Schwartz on 11/4/20. +// + +#include "Game.h" +#include "GAttractState.h" +#include "GGame.h" +#include "GEnemyProcess.h" +#include "GAttractProcess.h" +#include "GStarfield.h" +#include "GCamera.h" + +GAttractState::GAttractState() : BGameEngine(gViewPort) { + gGameEngine = this; + mPlayfield = new GStarfield(); + AddProcess(new GAttractProcess()); + GCamera::vx = GCamera::vy = 0; + GCamera::vz = 2; + + gDisplay.SetColor(COLOR_BLACK, 0,0,0); + for (TInt i=1; i<256; i++) { + gDisplay.SetColor(i, 255,255,255); + } + gDisplay.SetColor(COLOR_WHITE, 255, 255, 255); + gDisplay.SetColor(ASSAULT_COLOR, 255, 50, 50); + gDisplay.SetColor(BOMBER_COLOR, 50, 255, 50); + gDisplay.SetColor(SCOUT_COLOR, 255, 50, 255); + gDisplay.SetColor(EBULLET_COLOR, 50, 50, 255); + gDisplay.SetColor(BOMB_COLOR, 255, 255, 50); +} + +GAttractState::~GAttractState() noexcept { +} + diff --git a/Evade2/src/AttractState/GAttractState.h b/Evade2/src/AttractState/GAttractState.h new file mode 100644 index 0000000..b8f7923 --- /dev/null +++ b/Evade2/src/AttractState/GAttractState.h @@ -0,0 +1,18 @@ +// +// Created by Michael Schwartz on 11/4/20. +// + +#ifndef EVADE2_GATTRACTSTATE_H +#define EVADE2_GATTRACTSTATE_H + +#include "Game.h" + +class GAttractState : public BGameEngine { +public: + GAttractState(); + + ~GAttractState() OVERRIDE; +}; + + +#endif //EVADE2_GATTRACTSTATE_H diff --git a/Evade2/src/GGame.cpp b/Evade2/src/GGame.cpp index 670308b..561437c 100644 --- a/Evade2/src/GGame.cpp +++ b/Evade2/src/GGame.cpp @@ -1,16 +1,16 @@ #include "Game.h" #include "GGame.h" //#include "GPlayer.h" -#include "GameState/GCamera.h" +#include "common/GCamera.h" #include "GResources.h" + +// states #include "./GameState/GGameState.h" +#include "./SplashState/GSplashState.h" +#include "./AttractState/GAttractState.h" static TUint32 start; -BFont *gFont8x8, *gFont16x16; - -BViewPort gFullViewPort; - #ifdef DEBUG_MODE //TBool GGame::mDebug = ETrue; TBool GGame::mDebug = EFalse; @@ -23,64 +23,16 @@ TBool GGame::mDebug = EFalse; *******************************************************************************/ GGame::GGame() { + gGame = this; printf("Construct GGame\n"); - mDifficulty = 1; - mState = GAME_STATE_GAME; -#if 0 - mLocalData = ENull; - mLocalDataSize = 0; - - gFullViewPort.SetRect(TRect (0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1)); - - // Load Game Options -#ifdef ENABLE_OPTIONS - gOptions = new TOptions(); -#endif - -#ifdef ENABLE_AUDIO - gSoundPlayer.Init(6 /*channels*/); -#endif - - gDisplay.SetColor(COLOR_WHITE, 255, 255, 255); - gDisplay.SetColor(ASSAULT_COLOR, 255, 50, 50); - gDisplay.SetColor(BOMBER_COLOR, 50, 255, 50); - gDisplay.SetColor(SCOUT_COLOR, 255, 50, 255); - Camera::mZ = CAMERA_VZ; - -// const TUint8 BULLET_COLOR = 217; -// const TUint8 EBULLET_COLOR = 218; -// const TUint8 BOSS_COLOR = 219; -// const TUint8 SCOUT_COLOR = 222; -// const TUint8 STAR_COLOR = 223; - // preload bitmaps - // MAX_BITMAP is defined in GResource.h. - // for (TInt16 slot = 0; slot <= MAX_BBITMAP; slot++) { - // gResourceManager.PreloadBitmap(slot); - // } - - gResourceManager.LoadBitmap(CHARSET_8X8_BMP, FONT_8x8_SLOT, IMAGE_8x8); - gResourceManager.CacheBitmapSlot(FONT_8x8_SLOT); - gFont8x8 = new BFont(gResourceManager.GetBitmap(FONT_8x8_SLOT), FONT_8x8); - gResourceManager.LoadBitmap(CHARSET_16X16_BMP, FONT_16x16_SLOT, IMAGE_16x16); - gResourceManager.CacheBitmapSlot(FONT_16x16_SLOT); - gFont16x16 = new BFont(gResourceManager.GetBitmap(FONT_16x16_SLOT), FONT_16x16); - - gViewPort = new BViewPort(); - gViewPort->SetRect(TRect(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1)); - gViewPort->Offset(0, 0); - - mState = mNextState = -1; - gGameEngine = ENull; - mGameMenu = ENull; - mDebugMenu = ENull; - mInventory = ENull; -// SetState(GAME_STATE_SPLASH); <-- DEFAULT - SetState(GAME_STATE_MAIN_MENU); // <--- For debugging - start = Milliseconds(); - mShmoo.Set(0, 0, 0); - - mStarField = new GStarFieldProcess(); -#endif + mWave = 1; + mKills = 0; + mDifficulty = 1; + gVectorFont = new GVectorFont(); + gGameEngine = ENull; + mState = 0; + SetState(GAME_STATE_SPLASH); +// SetState(GAME_STATE_GAME); } GGame::~GGame() { @@ -96,126 +48,48 @@ GGame::~GGame() { ******************************************************************************* *******************************************************************************/ -BGameEngine *GGame::CurrentState() { -#if 0 - if (gGameEngine->IsPaused()) { - if (mGameMenu) return mGameMenu; - else if (mInventory) return mInventory; - else if (mDebugMenu) return mDebugMenu; - } -#endif - return gGameEngine; -} - -#if 0 -void GGame::ToggleInGameMenu() { - if (GPlayer::mGameOver || mDebugMenu || mInventory) { - return; - } - if (mGameMenu) { - delete mGameMenu; - mGameMenu = ENull; - gGameEngine->Resume(); - } - else { - mGameMenu = new GGameMenuState((GGameState *)gGameEngine); - gGameEngine->Pause(); - } - gControls.dKeys = 0; -} - -#endif - -#if 0 -void GGame::ToggleDebugMenu() { - if (GPlayer::mGameOver || mGameMenu || mInventory) { - return; - } - if (mDebugMenu) { - delete mDebugMenu; - mDebugMenu = ENull; - gGameEngine->Resume(); - } - else { - mDebugMenu = new GDebugMenuState(); - gGameEngine->Pause(); - } - gControls.dKeys = 0; -} -#endif - -/******************************************************************************* - ******************************************************************************* - *******************************************************************************/ - -#if 0 -void GGame::ToggleInventory() { -// if (GPlayer::mGameOver || mGameMenu) { -// return; -// } -// if (mInventory) { -// delete mInventory; -// mInventory = ENull; -// if (!mDebugMenu) { -// gGameEngine->Resume(); -// } -// } -// else { -// gGameEngine->Pause(); -// } -// gControls.dKeys = 0; -} -#endif +//BGameEngine *GGame::CurrentState() { +// return gGameEngine; +//} -/******************************************************************************* - ******************************************************************************* - *******************************************************************************/ -#if 0 -void GGame::SetState(TInt aNewState, TAny *aLocalData, TUint32 aSize) { - mNextState = aNewState; - if (aLocalData) { - delete (TUint8 *)mLocalData; - mLocalDataSize = aSize; - mLocalData = new TUint8[mLocalDataSize]; - memcpy((TUint8 *)mLocalData, (TUint8 *)aLocalData, mLocalDataSize); - } - else { - delete (TUint8 *)mLocalData; - mLocalData = ENull; - mLocalDataSize = 0; - } -} -#endif - -TInt GGame::GetState() { +TInt GGame::GetState() const { return mState; } -void GGame::StartGame(char *aGameName) { -#if 0 -#ifdef DEBUG_MODE - printf("START GAME (%s)\n", aGameName); -#endif - SetState( - mState == GAME_STATE_RESUME_GAME ? GAME_STATE_LOAD_SAVEGAME : GAME_STATE_RESUME_GAME, - aGameName, - strlen(aGameName)+1 - ); -#endif -} - -TBool GGame::IsGameState() { - TBool state = mState == GAME_STATE_RESUME_GAME || - mState == GAME_STATE_GAME || - mState == GAME_STATE_LOAD_SAVEGAME; - - if (!state) { - return EFalse; +void GGame::SetState(GAMESTATE aNewState) { + delete gGameEngine; + mState = aNewState; + switch (aNewState) { + case GAME_STATE_SPLASH: + printf("new State SPLASH\n"); + gGameEngine = new GSplashState(); + break; + case GAME_STATE_ATTRACT_MODE: + printf("new State ATTRACT\n"); + gGameEngine = new GAttractState(); + break; + case GAME_STATE_GAME: + printf("new State GAME\n"); + gGameEngine = new GGameState(); + break; + case GAME_STATE_MAIN_MENU: + printf("new State MAIN MENU\n"); + gGameEngine = new GGameState(); + break; + case GAME_STATE_VICTORY: + printf("new State VICTORY\n"); + gGameEngine = new GGameState(); + break; + case GAME_STATE_CREDITS: + printf("new State CREDITS\n"); + gGameEngine = new GAttractState(); + break; } - return ETrue; -// GGameState *s = (GGameState *)gGameEngine; -// return !s->IsGameOver(); +}; + +TBool GGame::IsGameState() const { + return mState == GAME_STATE_GAME; } /******************************************************************************* @@ -223,8 +97,6 @@ TBool GGame::IsGameState() { *******************************************************************************/ void GGame::Run() { - printf("run\n"); - gGameEngine = new GGameState(); TBool done = EFalse; while (!done) { Random(); // randomize diff --git a/Evade2/src/GGame.h b/Evade2/src/GGame.h index 0759679..97a3d06 100644 --- a/Evade2/src/GGame.h +++ b/Evade2/src/GGame.h @@ -9,18 +9,17 @@ class BGameEngine; class BFont; -enum { +enum GAMESTATE { GAME_STATE_SPLASH, GAME_STATE_MAIN_MENU, - GAME_STATE_LOAD_GAME, - GAME_STATE_MAIN_OPTIONS, - GAME_STATE_RESET_OPTIONS, +// GAME_STATE_LOAD_GAME, +// GAME_STATE_MAIN_OPTIONS, +// GAME_STATE_RESET_OPTIONS, GAME_STATE_ATTRACT_MODE, - GAME_STATE_RESET_GAME, +// GAME_STATE_RESET_GAME, GAME_STATE_GAME, - GAME_STATE_RESUME_GAME, - GAME_STATE_LOAD_SAVEGAME, - GAME_STATE_QUIT, +// GAME_STATE_RESUME_GAME, +// GAME_STATE_LOAD_SAVEGAME, GAME_STATE_VICTORY, GAME_STATE_CREDITS, }; @@ -35,27 +34,21 @@ class GGame : public BApplication { void Run(); public: -// void SetState(TInt aNewState, TAny *aLocalData = ENull, TUint32 aSize = 0); - void StartGame(char *aGameName); + void SetState(GAMESTATE aNewStae); - TInt GetState(); + TInt GetState() const; - TBool IsGameState(); + TBool IsGameState() const; - BGameEngine *CurrentState(); - - TUint16 mWave; - TUint16 mKills; +public: TUint8 mDifficulty; + TInt16 mKills; + TInt16 mWave; static TBool mDebug; protected: - TInt mState; - TInt mNextState; - BGameEngine *mGameMenu; - TRGB mShmoo; - -// GStarFieldProcess *mStarField; + TInt mState; + TRGB mShmoo; }; extern GGame *gGame; diff --git a/Evade2/src/GResources.h b/Evade2/src/GResources.h index 431723b..cc3740a 100644 --- a/Evade2/src/GResources.h +++ b/Evade2/src/GResources.h @@ -10,6 +10,7 @@ const TUint16 EVENT_SPELL_PROCESS_EXIT = 1; enum { FONT_8x8_SLOT, FONT_16x16_SLOT, + BKG_SLOT, SLOT_MAX, }; @@ -94,8 +95,9 @@ const TUint16 IMG_DAMAGE_UP = 40; const TUint8 COLOR_BLACK = 0; const TUint8 COLOR_WHITE = 1; const TUint8 COLOR_TEXT = 2; -const TUint8 COLOR_STAR = 3; -const TUint8 COLOR_HUD = 4; +const TUint8 COLOR_TEXT_BG = 3; +const TUint8 COLOR_STAR = 4; +const TUint8 COLOR_HUD = 5; const TUint8 COLOR_BLUE = 201; const TUint8 COLOR_GREEN = 202; diff --git a/Evade2/src/Game.h b/Evade2/src/Game.h index 2f4f11a..99eaa4b 100644 --- a/Evade2/src/Game.h +++ b/Evade2/src/Game.h @@ -23,7 +23,7 @@ const TFloat COLLISION_RADIUS = 64; #undef FRAME_RATE_INFO #define ENABLE_AUDIO -//#undef ENABLE_AUDIO +#undef ENABLE_AUDIO #define ENABLE_ROTATING_TEXT //#undef ENABLE_ROTATING_TEXT diff --git a/Evade2/src/GameState/GEnemyProcess.cpp b/Evade2/src/GameState/GEnemyProcess.cpp index 3670f7d..11e90ef 100644 --- a/Evade2/src/GameState/GEnemyProcess.cpp +++ b/Evade2/src/GameState/GEnemyProcess.cpp @@ -13,6 +13,20 @@ #define FIRE_TIME (60 / gGame->mDifficulty + Random(1, 60 / gGame->mDifficulty)) +const TInt8 *GEnemyProcess::Graphic(TInt aType) { + switch (aType) { + case ENEMY_ASSAULT: + return (const TInt8 *)&enemy_assault_1_img; + case ENEMY_BOMBER: + return (const TInt8 *)&enemy_heavy_bomber_1_img; + case ENEMY_SCOUT: + return (const TInt8 *)&enemy_scout_1_img; + default: + Panic("Invalid enemy type: %d\n", aType); + } + return ENull; +} + GEnemyProcess::GEnemyProcess() { mSprite = new GVectorSprite(STYPE_ENEMY); gGameEngine->AddSprite(mSprite); @@ -154,7 +168,6 @@ TBool GEnemyProcess::StateSeek() { if (o->z - GCamera::z < Random(256, 512)) { o->mState = -1; mState = ESTATE_RUNAWAY; -// me->sleep(1, run_away); return ETrue; } @@ -166,12 +179,10 @@ TBool GEnemyProcess::StateEvade() { if (o->z - GCamera::z > 512) { o->mState = 1; mState = ESTATE_RUNAWAY; -// me->sleep(1, run_away); return ETrue; } if (death()) { mState = ESTATE_EXPLODE; -// me->sleep(1, explode); return ETrue; } bank(15); @@ -213,7 +224,6 @@ TBool GEnemyProcess::StateOrbit() { o->z = GCamera::z + sin(rad) * 256; } -// me->sleep(1); return ETrue; } @@ -226,7 +236,6 @@ TBool GEnemyProcess::StateWaitInit() { o->mTimer = 1; } o->mTimer--; -// me->sleep(1); return ETrue; } @@ -245,12 +254,10 @@ TBool GEnemyProcess::StateRunAway() { } if (death()) { mState = ESTATE_EXPLODE; -// me->sleep(1, explode); return ETrue; } bank(); fire(); -// me->sleep(1); return ETrue; } diff --git a/Evade2/src/GameState/GEnemyProcess.h b/Evade2/src/GameState/GEnemyProcess.h index 5e47fcb..761f835 100644 --- a/Evade2/src/GameState/GEnemyProcess.h +++ b/Evade2/src/GameState/GEnemyProcess.h @@ -24,20 +24,32 @@ enum EState { class GEnemyProcess : public BProcess { public: GEnemyProcess(); - ~GEnemyProcess(); + + ~GEnemyProcess() OVERRIDE; + +public: + static const TInt8 *Graphic(TInt aType); public: - TBool RunBefore(); - TBool RunAfter(); + TBool RunBefore() OVERRIDE; + + TBool RunAfter() OVERRIDE; private: void init_assault(TBool left); + void init_scout(); + void init_bomber(); + void init(); + void respawn(); + TBool death(); + void fire(); + void bank(TInt16 delta = 45); protected: @@ -45,11 +57,17 @@ class GEnemyProcess : public BProcess { protected: TBool StateSeek(); + TBool StateEvade(); + TBool StateOrbit(); + TBool StateWaitInit(); + TBool StateRunAway(); + TBool StateExplode(); + protected: EState mState; diff --git a/Evade2/src/GameState/GGameState.cpp b/Evade2/src/GameState/GGameState.cpp index 37c1cc6..5ad85ad 100644 --- a/Evade2/src/GameState/GGameState.cpp +++ b/Evade2/src/GameState/GGameState.cpp @@ -3,7 +3,7 @@ // #include "GGameState.h" -#include "GGamePlayfield.h" +#include "GStarfield.h" #include "GPlayerProcess.h" #include "GEnemyProcess.h" @@ -12,7 +12,7 @@ GGameState *gGameState; GGameState::GGameState() : BGameEngine(gViewPort) { gGameEngine = this; gGameState = this; - mPlayfield = new GGamePlayfield(); + mPlayfield = new GStarfield(); // set colors gDisplay.SetColor(COLOR_BLACK, 0,0,0); for (TInt i=1; i<256; i++) { diff --git a/Evade2/src/MainMenuState/GMainMenu.cpp b/Evade2/src/MainMenuState/GMainMenu.cpp new file mode 100644 index 0000000..fe91034 --- /dev/null +++ b/Evade2/src/MainMenuState/GMainMenu.cpp @@ -0,0 +1,12 @@ +// +// Created by Michael Schwartz on 11/4/20. +// + +#include "GMainMenu.h" +#include "GStarfield.h" + +GMainMenu::GMainMenu() : BGameEngine(gViewPort) { + mPlayfield = new GStarfield(); +} + +GMainMenu::~GMainMenu() noexcept {} \ No newline at end of file diff --git a/Evade2/src/MainMenuState/GMainMenu.h b/Evade2/src/MainMenuState/GMainMenu.h new file mode 100644 index 0000000..5c52ac5 --- /dev/null +++ b/Evade2/src/MainMenuState/GMainMenu.h @@ -0,0 +1,18 @@ +// +// Created by Michael Schwartz on 11/4/20. +// + +#ifndef EVADE2_GMAINMENU_H +#define EVADE2_GMAINMENU_H + +#include "Game.h" + +class GMainMenu : public BGameEngine { +public: + GMainMenu(); + + ~GMainMenu() OVERRIDE; +}; + + +#endif //EVADE2_GMAINMENU_H diff --git a/Evade2/src/MainMenuState/GMainMenuProcess.cpp b/Evade2/src/MainMenuState/GMainMenuProcess.cpp new file mode 100644 index 0000000..18c15df --- /dev/null +++ b/Evade2/src/MainMenuState/GMainMenuProcess.cpp @@ -0,0 +1,5 @@ +// +// Created by Michael Schwartz on 11/4/20. +// + +#include "GMainMenuProcess.h" diff --git a/Evade2/src/MainMenuState/GMainMenuProcess.h b/Evade2/src/MainMenuState/GMainMenuProcess.h new file mode 100644 index 0000000..56ed2d0 --- /dev/null +++ b/Evade2/src/MainMenuState/GMainMenuProcess.h @@ -0,0 +1,24 @@ +// +// Created by Michael Schwartz on 11/4/20. +// + +#ifndef EVADE2_GMAINMENUPROCESS_H +#define EVADE2_GMAINMENUPROCESS_H + +#include "Game.h" + +class GMainMenuProcess : public BProcess { +public: + GMainMenuProcess(); + + ~GMainMenuProcess(); + +public: + TBool RunBefore(); + + TBool RunAfter(); + +}; + + +#endif //EVADE2_GMAINMENUPROCESS_H diff --git a/Evade2/old/SplashState/GSplashPlayfield.cpp b/Evade2/src/SplashState/GSplashPlayfield.cpp similarity index 100% rename from Evade2/old/SplashState/GSplashPlayfield.cpp rename to Evade2/src/SplashState/GSplashPlayfield.cpp diff --git a/Evade2/old/SplashState/GSplashPlayfield.h b/Evade2/src/SplashState/GSplashPlayfield.h similarity index 100% rename from Evade2/old/SplashState/GSplashPlayfield.h rename to Evade2/src/SplashState/GSplashPlayfield.h diff --git a/Evade2/old/SplashState/GSplashProcess.cpp b/Evade2/src/SplashState/GSplashProcess.cpp similarity index 91% rename from Evade2/old/SplashState/GSplashProcess.cpp rename to Evade2/src/SplashState/GSplashProcess.cpp index 277d5dd..5a797bc 100644 --- a/Evade2/old/SplashState/GSplashProcess.cpp +++ b/Evade2/src/SplashState/GSplashProcess.cpp @@ -4,8 +4,8 @@ //static const char *splash_message2 = "Press any button"; GSplashProcess::GSplashProcess() : BProcess() { - mColor = 0; - mState = STATE_FADEIN; + mColor = 0; + mState = STATE_FADEIN; // mFont = new BFont(gResourceManager.GetBitmap(FONT_16x16_SLOT), FONT_16x16); // mCurrentText = splash_message1; } @@ -65,12 +65,12 @@ void GSplashProcess::RenderText() { TBool GSplashProcess::RunAfter() { if (gControls.WasPressed(BUTTON_ANY)) { // } || --mTimer <= 0) { - gGame->SetState(GAME_STATE_MAIN_MENU); -// gGame->SetState(GAME_STATE_VICTORY); + gGame->SetState(GAME_STATE_ATTRACT_MODE); #ifdef ENABLE_AUDIO - //gSoundPlayer.SfxStartGame(); + gSoundPlayer.SfxStartGame(); #endif + return EFalse; } // switch (mState) { diff --git a/Evade2/old/SplashState/GSplashProcess.h b/Evade2/src/SplashState/GSplashProcess.h similarity index 100% rename from Evade2/old/SplashState/GSplashProcess.h rename to Evade2/src/SplashState/GSplashProcess.h diff --git a/Evade2/old/SplashState/GSplashState.cpp b/Evade2/src/SplashState/GSplashState.cpp similarity index 62% rename from Evade2/old/SplashState/GSplashState.cpp rename to Evade2/src/SplashState/GSplashState.cpp index 931fd42..91f31bf 100644 --- a/Evade2/old/SplashState/GSplashState.cpp +++ b/Evade2/src/SplashState/GSplashState.cpp @@ -1,11 +1,16 @@ #include "Game.h" #include "GSplashPlayfield.h" #include "GSplashProcess.h" +#include "GSplashState.h" GSplashState::GSplashState() : BGameEngine(gViewPort) { + gGameEngine = this; mPlayfield = new GSplashPlayfield(); AddProcess(new GSplashProcess()); } -GSplashState::~GSplashState() = default; +GSplashState::~GSplashState() { + delete mPlayfield; + mPlayfield = ENull; +} diff --git a/Evade2/old/SplashState/GSplashState.h b/Evade2/src/SplashState/GSplashState.h similarity index 86% rename from Evade2/old/SplashState/GSplashState.h rename to Evade2/src/SplashState/GSplashState.h index 96286e2..0735338 100644 --- a/Evade2/old/SplashState/GSplashState.h +++ b/Evade2/src/SplashState/GSplashState.h @@ -7,7 +7,7 @@ class GSplashState : public BGameEngine { public: GSplashState(); - virtual ~GSplashState(); + ~GSplashState() OVERRIDE; }; diff --git a/Evade2/src/GameState/GCamera.cpp b/Evade2/src/common/GCamera.cpp similarity index 100% rename from Evade2/src/GameState/GCamera.cpp rename to Evade2/src/common/GCamera.cpp diff --git a/Evade2/src/GameState/GCamera.h b/Evade2/src/common/GCamera.h similarity index 100% rename from Evade2/src/GameState/GCamera.h rename to Evade2/src/common/GCamera.h diff --git a/Evade2/src/GameState/GGamePlayfield.cpp b/Evade2/src/common/GStarfield.cpp similarity index 86% rename from Evade2/src/GameState/GGamePlayfield.cpp rename to Evade2/src/common/GStarfield.cpp index dde66e1..b7cf405 100644 --- a/Evade2/src/GameState/GGamePlayfield.cpp +++ b/Evade2/src/common/GStarfield.cpp @@ -2,20 +2,20 @@ // Created by Michael Schwartz on 10/29/20. // -#include "GGamePlayfield.h" +#include "GStarfield.h" #include "GCamera.h" -GGamePlayfield::GGamePlayfield() : BPlayfield() { +GStarfield::GStarfield() : BPlayfield() { for (TInt i = 0; i < NUM_STARS; i++) { InitStar(i); } } -GGamePlayfield::~GGamePlayfield() noexcept { +GStarfield::~GStarfield() noexcept { } -void GGamePlayfield::Render() { +void GStarfield::Render() { gDisplay.renderBitmap->Clear(0); TFloat cz = GCamera::z, sw = TFloat(SCREEN_WIDTH), @@ -50,7 +50,7 @@ void GGamePlayfield::Render() { } } -void GGamePlayfield::InitStar(TInt aIndex) { +void GStarfield::InitStar(TInt aIndex) { mStarX[aIndex] = TFloat(256) - Random(0, 512) + GCamera::x; mStarY[aIndex] = TFloat(256) - Random(0, 512) + GCamera::y; mStarZ[aIndex] = GCamera::z + Random(200, 512); diff --git a/Evade2/src/GameState/GGamePlayfield.h b/Evade2/src/common/GStarfield.h similarity index 60% rename from Evade2/src/GameState/GGamePlayfield.h rename to Evade2/src/common/GStarfield.h index 19c662d..cca0e8f 100644 --- a/Evade2/src/GameState/GGamePlayfield.h +++ b/Evade2/src/common/GStarfield.h @@ -2,18 +2,18 @@ // Created by Michael Schwartz on 10/29/20. // -#ifndef EVADE2_GGAMEPLAYFIELD_H -#define EVADE2_GGAMEPLAYFIELD_H +#ifndef EVADE2_GSTARFIELD_H +#define EVADE2_GSTARFIELD_H #include const int NUM_STARS = 128; -class GGamePlayfield : public BPlayfield { +class GStarfield : public BPlayfield { public: - GGamePlayfield(); + GStarfield(); - ~GGamePlayfield(); + ~GStarfield(); public: void Render() OVERRIDE; @@ -26,4 +26,4 @@ class GGamePlayfield : public BPlayfield { }; -#endif //EVADE2_GGAMEPLAYFIELD_H +#endif //EVADE2_GSTARFIELD_H diff --git a/Evade2/src/common/GVectorFont.cpp b/Evade2/src/common/GVectorFont.cpp index 502a98e..32f307f 100644 --- a/Evade2/src/common/GVectorFont.cpp +++ b/Evade2/src/common/GVectorFont.cpp @@ -7,196 +7,37 @@ * See: https://github.com/arduino/Arduino/blob/master/hardware/arduino/avr/cores/arduino/Print.cpp */ +#include "Game.h" #include "charset.h" -#include - -const TInt8 *charset[] = { - ENull, // space - font_emark, -#ifdef FULL_CHARSET - font_dquote, -#else - ENull, -#endif -#ifdef FULL_CHARSET - font_pound, // # -#else - ENull, -#endif -#ifdef FULL_CHARSET - font_dollar, // $ -#else - ENull, -#endif -#ifdef FULL_CHARSET - font_percent, // % -#else - ENull, -#endif -#ifdef FULL_CHARSET - font_amp, // & -#else - ENull, -#endif -#ifdef FULL_CHARSET - font_squote, // ' -#else - ENull, -#endif -#ifdef FULL_CHARSET - font_lparen, // ( -#else - ENull, -#endif -#ifdef FULL_CHARSET - font_rparen, // ) -#else - ENull, -#endif -#ifdef FULL_CHARSET - font_asterisk, // * -#else - ENull, -#endif -#ifdef FULL_CHARSET - font_plus, -#else - ENull, -#endif -#ifdef FULL_CHARSET - font_comma, -#else - ENull, -#endif -#ifdef FULL_CHARSET - font_minus, -#else - ENull, -#endif - font_period, - font_fslash, - font_0, - font_1, - font_2, - font_3, - font_4, - font_5, - font_6, - font_7, - font_8, - font_9, - font_colon, -#ifdef full_charset - font_semicolon, -#else - ENull, -#endif -#ifdef full_charset - font_lt, // < -#else - ENull, -#endif -#ifdef full_charset - font_eq, // = -#else - ENull, -#endif -#ifdef full_charset - font_gt, // > -#else - ENull, -#endif -#ifdef full_charset - font_qmark, -#else - ENull, -#endif -#ifdef full_charset - font_at, // @ -#else - ENull, -#endif - font_a, - font_b, - font_c, - font_d, - font_e, - font_f, - font_g, - font_h, - font_i, - font_j, - font_k, - font_l, - font_m, - font_n, - font_o, - font_p, - font_q, - font_r, - font_s, - font_t, - font_u, - font_v, - font_w, - font_x, - font_y, - font_z, -#ifdef full_charset - font_lt, // [ -#else - ENull, -#endif -#ifdef full_charset - font_bslash, // '\' -#else - ENull, -#endif -#ifdef full_charset - font_gt, // ] -#else - ENull, -#endif -#ifdef full_charset - font_caret, // ^ -#else - ENull, -#endif -#ifdef full_charset - font_uscore, // _ -#else - ENull, -#endif - ENull, // `` -}; +GVectorFont *gVectorFont; +// constructor GVectorFont::GVectorFont() { - scale = 0x100; + scale = 1.0; color = COLOR_TEXT; + gVectorFont = this; } #ifdef ENABLE_ROTATING_TEXT -TInt8 GVectorFont::print_string_rotatedx(TInt8 x, TInt8 y, TFloat theta, const char *s) { +TInt16 GVectorFont::print_string_rotatedx(TFloat x, TFloat y, TFloat theta, const char *s) { theta = float(theta) * 3.1415926 / 180; TFloat cost = cos(theta), sint = sin(theta); const char *p = s; - TFloat fscale = TFloat(scale >> 8) + TFloat(scale & 0xff) / 256.0; - - const TInt8 size = 9; + const TInt16 size = 9; - TInt8 xo = x; + TInt16 xo = x; while (char c = *p++) { - const TInt8 *glyph = charset[toupper(c) - 32]; + auto *glyph = (const TInt16 *)charset[toupper(c) - 32]; if (glyph) { - TInt8 lines = *glyph++; + TInt16 lines = *glyph++; - for (TInt8 i = 0; i < lines; i++) { - TFloat x0 = (TInt8)*glyph++ * fscale + x, - y0 = (TInt8)*glyph++ * fscale + y, - x1 = (TInt8)*glyph++ * fscale + x, - y1 = (TInt8)*glyph++ * fscale + y; + for (TInt16 i = 0; i < lines; i++) { + TFloat x0 = *glyph++ * scale + x, + y0 = *glyph++ * scale + y, + x1 = *glyph++ * scale + x, + y1 = *glyph++ * scale + y; gDisplay.renderBitmap->DrawLine( gViewPort, @@ -206,26 +47,25 @@ TInt8 GVectorFont::print_string_rotatedx(TInt8 x, TInt8 y, TFloat theta, const c ((y1 - y) * sint + cost + y), color); } - x += size * fscale; + x += size * scale; } else { - x += 6 * fscale; + x += 6 * scale; } } return x - xo; } #endif -TInt8 GVectorFont::write(TInt8 x, TInt8 y, char c) { +TInt16 GVectorFont::write(TFloat x, TFloat y, char c) { const TInt8 *glyph; - const TInt8 width = 9; + const TInt16 width = 9; - TFloat fscale = TFloat(scale >> 8) + TFloat(scale & 0xff) / 256.0; - glyph = charset[toupper(c) - 32]; + glyph = (TInt8 *)charset[toupper(c) - 32]; if (glyph) { TInt8 lines = *glyph++; - for (TInt8 i = 0; i < lines; i++) { + for (TInt16 i = 0; i < lines; i++) { TInt8 x0 = *glyph++, y0 = *glyph++, x1 = *glyph++, @@ -233,24 +73,24 @@ TInt8 GVectorFont::write(TInt8 x, TInt8 y, char c) { gDisplay.renderBitmap->DrawLine( gViewPort, - x + x0 * fscale, y + y0 * fscale, - x + x1 * fscale, y + y1 * fscale, + x + x0 * scale, y + y0 * scale, + x + x1 * scale, y + y1 * scale, color); } } - return width * fscale; + return width * scale; } -TInt8 GVectorFont::print_string(TInt8 x, TInt8 y, char *s) { - TInt8 xx = x; +TInt16 GVectorFont::print_string(TFloat x, TFloat y, char *s) { + TInt16 xx = x; while (char c = *s++) { - TInt8 width = write(x, y, c); + TInt16 width = write(x, y, c); x += width; } return x - xx; // width of string printed } -TInt8 GVectorFont::print_long(TInt8 x, TInt8 y, TInt64 n, TInt8 base) { +TInt16 GVectorFont::print_long(TFloat x, TFloat y, TInt64 n, TInt16 base) { char buf[8 * sizeof(TInt64) + 1]; // Assumes 8-bit chars plus zero byte. char *str = &buf[sizeof(buf) - 1]; @@ -271,8 +111,8 @@ TInt8 GVectorFont::print_long(TInt8 x, TInt8 y, TInt64 n, TInt8 base) { } #ifdef PRINTF_TFloat -TInt8 GVectorFont::print_float(TInt8 x, TInt8 y, double number, TInt8 digits) { - TInt8 xx = x; +TInt16 GVectorFont::print_float(TInt16 x, TInt16 y, double number, TInt16 digits) { + TInt16 xx = x; if (isnan(number)) { x += write(x, y, 'n'); x += write(x, y, 'a'); @@ -327,9 +167,9 @@ TInt8 GVectorFont::print_float(TInt8 x, TInt8 y, double number, TInt8 digits) { } #endif -TInt8 GVectorFont::printf(TInt8 x, TInt8 y, const char *s, ...) { +TInt16 GVectorFont::printf(TFloat x, TFloat y, const char *s, ...) { va_list ap; - TInt8 xx = x; + TInt16 xx = x; char c; const char *p = s; va_start(ap, s); diff --git a/Evade2/src/common/GVectorFont.h b/Evade2/src/common/GVectorFont.h index 8153289..dca252c 100644 --- a/Evade2/src/common/GVectorFont.h +++ b/Evade2/src/common/GVectorFont.h @@ -8,19 +8,21 @@ class GVectorFont{ GVectorFont(); public: - TUint16 scale; // 8.8 fixed point + TFloat scale; TUint8 color; // color to render text in public: // these routine return the width of whatever is printed to the screen - TInt8 write(TInt8 x, TInt8 y, char c); - TInt8 printf(TInt8 x, TInt8 y, const char *s, ...); + TInt16 write(TFloat x, TFloat y, char c); + TInt16 printf(TFloat x, TFloat y, const char *s, ...); #ifdef ENABLE_ROTATING_TEXT - TInt8 print_string_rotatedx(TInt8 x, TInt8 y, TFloat angle, const char *s); + TInt16 print_string_rotatedx(TFloat x, TFloat y, TFloat angle, const char *s); #endif - TInt8 print_string(TInt8 x, TInt8 y, char *s); - TInt8 print_long(TInt8 x, TInt8 y, TInt64 n, TInt8 base = 10); - TInt8 print_float(TInt8 x, TInt8 y, TFloat number, TInt8 digits = 2); + TInt16 print_string(TFloat x, TFloat y, char *s); + TInt16 print_long(TFloat x, TFloat y, TInt64 n, TInt16 base = 10); +// TInt16 print_float(TInt16 x, TInt16 y, TFloat number, TInt16 digits = 2); }; +extern GVectorFont *gVectorFont; + #endif diff --git a/Evade2/src/common/GVectorSprite.cpp b/Evade2/src/common/GVectorSprite.cpp index d0f9f7b..7714cea 100644 --- a/Evade2/src/common/GVectorSprite.cpp +++ b/Evade2/src/common/GVectorSprite.cpp @@ -1,5 +1,5 @@ #include "GVectorSprite.h" -#include "GameState/GCamera.h" +#include "GCamera.h" void GVectorSprite::SetLines(const TInt8 *aLines) { mLines = aLines; diff --git a/Evade2/src/common/GVectorSprite.h b/Evade2/src/common/GVectorSprite.h index 8d8930d..2386f52 100644 --- a/Evade2/src/common/GVectorSprite.h +++ b/Evade2/src/common/GVectorSprite.h @@ -18,7 +18,7 @@ struct vec_segment_u8 { class GVectorSprite : public BSprite { public: - GVectorSprite(TUint64 aType = STYPE_DEFAULT) : BSprite(0 , 0, ENull, aType) { + explicit GVectorSprite(TUint64 aType = STYPE_DEFAULT) : BSprite(0 , 0, ENull, aType) { mColor = COLOR_WHITE; mPad = 0; x = y = z = 0; @@ -28,15 +28,11 @@ class GVectorSprite : public BSprite { mLines = ENull; } - void StartAnimation() { - printf("GVectorSprite::StartAnimation()\n"); - } - - TBool DrawVectorGraphic(const TInt8 *graphic, TFloat x, TFloat y, TFloat theta, TFloat scaleFactor, TUint8 color) { + static TBool DrawVectorGraphic(const TInt8 *graphic, TFloat x, TFloat y, TFloat theta, TFloat scaleFactor, TUint8 color) { return ExplodeVectorGraphic(graphic, x, y, theta, scaleFactor, 0, color); } - TBool ExplodeVectorGraphic(const TInt8 *graphic, TFloat x, TFloat y, + static TBool ExplodeVectorGraphic(const TInt8 *graphic, TFloat x, TFloat y, TFloat theta, TFloat scaleFactor, TInt8 step, TUint8 color); TBool Render(BViewPort *aViewPort) OVERRIDE; diff --git a/Evade2/src/common/charset.h b/Evade2/src/common/charset.h index 56a1ad4..bcdff3e 100644 --- a/Evade2/src/common/charset.h +++ b/Evade2/src/common/charset.h @@ -762,4 +762,164 @@ const TInt8 font_amp[] = { }; #endif +const TInt8 *charset[] = { + ENull, // space + font_emark, +#ifdef FULL_CHARSET + font_dquote, +#else + ENull, +#endif +#ifdef FULL_CHARSET + font_pound, // # +#else + ENull, +#endif +#ifdef FULL_CHARSET + font_dollar, // $ +#else + ENull, +#endif +#ifdef FULL_CHARSET + font_percent, // % +#else + ENull, +#endif +#ifdef FULL_CHARSET + font_amp, // & +#else + ENull, +#endif +#ifdef FULL_CHARSET + font_squote, // ' +#else + ENull, +#endif +#ifdef FULL_CHARSET + font_lparen, // ( +#else + ENull, +#endif +#ifdef FULL_CHARSET + font_rparen, // ) +#else + ENull, +#endif +#ifdef FULL_CHARSET + font_asterisk, // * +#else + ENull, +#endif +#ifdef FULL_CHARSET + font_plus, +#else + ENull, +#endif +#ifdef FULL_CHARSET + font_comma, +#else + ENull, +#endif +#ifdef FULL_CHARSET + font_minus, +#else + ENull, +#endif + font_period, + font_fslash, + font_0, + font_1, + font_2, + font_3, + font_4, + font_5, + font_6, + font_7, + font_8, + font_9, + font_colon, +#ifdef full_charset + font_semicolon, +#else + ENull, +#endif +#ifdef full_charset + font_lt, // < +#else + ENull, +#endif +#ifdef full_charset + font_eq, // = +#else + ENull, +#endif +#ifdef full_charset + font_gt, // > +#else + ENull, +#endif +#ifdef full_charset + font_qmark, +#else + ENull, +#endif +#ifdef full_charset + font_at, // @ +#else + ENull, +#endif + font_a, + font_b, + font_c, + font_d, + font_e, + font_f, + font_g, + font_h, + font_i, + font_j, + font_k, + font_l, + font_m, + font_n, + font_o, + font_p, + font_q, + font_r, + font_s, + font_t, + font_u, + font_v, + font_w, + font_x, + font_y, + font_z, +#ifdef full_charset + font_lt, // [ +#else + ENull, +#endif +#ifdef full_charset + font_bslash, // '\' +#else + ENull, +#endif +#ifdef full_charset + font_gt, // ] +#else + ENull, +#endif +#ifdef full_charset + font_caret, // ^ +#else + ENull, +#endif +#ifdef full_charset + font_uscore, // _ +#else + ENull, +#endif + ENull, // `` +}; + #endif diff --git a/Evade2/src/img/README.md b/Evade2/src/img/README.md new file mode 100644 index 0000000..c552948 --- /dev/null +++ b/Evade2/src/img/README.md @@ -0,0 +1,4 @@ +# Vector images + +This directory contains vector images used in the game. They were created as SVG, and converted into +code suitable for our rendering routines. From bced345b573d1a0cc72acb4a6ff6200904634841 Mon Sep 17 00:00:00 2001 From: Michael Schwartz Date: Fri, 6 Nov 2020 16:40:35 -0800 Subject: [PATCH 6/6] almost done... need to test Boss, need to implement asteroids, need to respawn enemies/etc. after boss, needs game over --- Evade2/CMakeLists.txt | 69 +- Evade2/src/AttractState/GAttractProcess.cpp | 21 +- Evade2/src/AttractState/GAttractState.cpp | 15 +- Evade2/src/GGame.cpp | 43 +- Evade2/src/GGame.h | 13 +- Evade2/src/Game.h | 2 + Evade2/src/GameState/GBossProcess.cpp | 593 ++++++++++++++++++ Evade2/src/GameState/GBossProcess.h | 43 ++ Evade2/src/GameState/GEnemyBulletProcess.cpp | 14 +- Evade2/src/GameState/GEnemyProcess.cpp | 53 +- Evade2/src/GameState/GGameState.cpp | 29 +- Evade2/src/GameState/GGameState.h | 16 +- Evade2/src/GameState/GNextWaveProcess.cpp | 36 ++ Evade2/src/GameState/GNextWaveProcess.h | 25 + Evade2/src/GameState/GPlayerBulletProcess.cpp | 16 +- Evade2/src/GameState/GPlayerProcess.cpp | 22 +- Evade2/src/MainMenuState/GMainMenu.cpp | 12 - Evade2/src/MainMenuState/GMainMenu.h | 18 - Evade2/src/MainMenuState/GMainMenuProcess.cpp | 44 ++ Evade2/src/MainMenuState/GMainMenuProcess.h | 3 + Evade2/src/MainMenuState/GMainMenuState.cpp | 18 + Evade2/src/MainMenuState/GMainMenuState.h | 18 + Evade2/src/SplashState/GSplashProcess.cpp | 2 +- Evade2/src/common/GCamera.cpp | 61 +- Evade2/src/common/GCamera.h | 21 +- Evade2/src/common/GStarfield.cpp | 13 +- Evade2/src/common/GVectorFont.cpp | 7 +- Evade2/src/common/GVectorSprite.cpp | 14 +- 28 files changed, 989 insertions(+), 252 deletions(-) create mode 100644 Evade2/src/GameState/GBossProcess.cpp create mode 100644 Evade2/src/GameState/GBossProcess.h create mode 100644 Evade2/src/GameState/GNextWaveProcess.cpp create mode 100644 Evade2/src/GameState/GNextWaveProcess.h delete mode 100644 Evade2/src/MainMenuState/GMainMenu.cpp delete mode 100644 Evade2/src/MainMenuState/GMainMenu.h create mode 100644 Evade2/src/MainMenuState/GMainMenuState.cpp create mode 100644 Evade2/src/MainMenuState/GMainMenuState.h diff --git a/Evade2/CMakeLists.txt b/Evade2/CMakeLists.txt index af1169f..2d20388 100644 --- a/Evade2/CMakeLists.txt +++ b/Evade2/CMakeLists.txt @@ -25,63 +25,54 @@ INCLUDE(${CMAKE_CURRENT_SOURCE_DIR}/creative-engine/CreativeEngine.cmake) SET(EVADE2_INCLUDE_DIRS - ${CMAKE_SOURCE_DIR}/src - ${CMAKE_SOURCE_DIR}/src/resources - ${CMAKE_SOURCE_DIR}/src/common -# ${CMAKE_SOURCE_DIR}/src/LoadGameState - ${CMAKE_SOURCE_DIR}/src/GameState -# ${CMAKE_SOURCE_DIR}/src/GameState/environment -# ${CMAKE_SOURCE_DIR}/src/GameState/player -# ${CMAKE_SOURCE_DIR}/src/GameState/inventory -# ${CMAKE_SOURCE_DIR}/src/GameState/enemies -# ${CMAKE_SOURCE_DIR}/src/GameState/enemies/final-boss -# ${CMAKE_SOURCE_DIR}/src/GameState/enemies/grunts -# ${CMAKE_SOURCE_DIR}/src/GameState/enemies/mid-bosses -# ${CMAKE_SOURCE_DIR}/src/GameState/status -# ${CMAKE_SOURCE_DIR}/src/img/ -# ${CMAKE_SOURCE_DIR}/src/AttractState -# ${CMAKE_SOURCE_DIR}/src/GameMenuState -# ${CMAKE_SOURCE_DIR}/src/DebugMenuState -# ${CMAKE_SOURCE_DIR}/src/GameOverState -# ${CMAKE_SOURCE_DIR}/src/VictoryState -# ${CMAKE_SOURCE_DIR}/src/MainMenuState -# ${CMAKE_SOURCE_DIR}/src/MainOptionsState - ${CMAKE_SOURCE_DIR}/src/SplashState -# ${CMAKE_SOURCE_DIR}/src/CreditsState -# ${CMAKE_SOURCE_DIR}/src/ResetState - ${CMAKE_BINARY_DIR}/usr/local/include -) + ${CMAKE_SOURCE_DIR}/src + ${CMAKE_SOURCE_DIR}/src/resources + ${CMAKE_SOURCE_DIR}/src/common + ${CMAKE_SOURCE_DIR}/src/SplashState + ${CMAKE_SOURCE_DIR}/src/AttractState + ${CMAKE_SOURCE_DIR}/src/MainMenuState + ${CMAKE_SOURCE_DIR}/src/GameState + # ${CMAKE_SOURCE_DIR}/src/img/ + # ${CMAKE_SOURCE_DIR}/src/GameMenuState + # ${CMAKE_SOURCE_DIR}/src/DebugMenuState + # ${CMAKE_SOURCE_DIR}/src/GameOverState + # ${CMAKE_SOURCE_DIR}/src/VictoryState + # ${CMAKE_SOURCE_DIR}/src/MainOptionsState + # ${CMAKE_SOURCE_DIR}/src/CreditsState + # ${CMAKE_SOURCE_DIR}/src/ResetState + ${CMAKE_BINARY_DIR}/usr/local/include + ) INCLUDE_DIRECTORIES( - ${EVADE2_INCLUDE_DIRS} - ${CREATIVE_ENGINE_INCLUDE_DIRS} + ${EVADE2_INCLUDE_DIRS} + ${CREATIVE_ENGINE_INCLUDE_DIRS} ) # gather Modite sources FILE(GLOB_RECURSE EVADE2_SRC RELATIVE ${CMAKE_SOURCE_DIR} "src/*.cpp") ADD_EXECUTABLE( - ${PROJECT_NAME} - Resources.bin - ${CREATIVE_ENGINE_SOURCE_FILES} - ${EVADE2_SRC} - src/GameState/GGameState.cpp src/GameState/GGameState.h src/common/GStarfield.cpp src/common/GStarfield.h src/GameState/GPlayerBulletProcess.cpp src/GameState/GPlayerBulletProcess.h src/main.cpp src/GameState/GEnemyProcess.cpp src/GameState/GEnemyProcess.h src/GameState/GEnemyBulletProcess.cpp src/GameState/GEnemyBulletProcess.h src/AttractState/GAttractState.cpp src/AttractState/GAttractState.h src/AttractState/GAttractProcess.cpp src/AttractState/GAttractProcess.h src/MainMenuState/GMainMenu.cpp src/MainMenuState/GMainMenu.h src/MainMenuState/GMainMenuProcess.cpp src/MainMenuState/GMainMenuProcess.h) + ${PROJECT_NAME} + Resources.bin + ${CREATIVE_ENGINE_SOURCE_FILES} + ${EVADE2_SRC} + src/GameState/GGameState.cpp src/GameState/GGameState.h src/common/GStarfield.cpp src/common/GStarfield.h src/GameState/GPlayerBulletProcess.cpp src/GameState/GPlayerBulletProcess.h src/main.cpp src/GameState/GEnemyProcess.cpp src/GameState/GEnemyProcess.h src/GameState/GEnemyBulletProcess.cpp src/GameState/GEnemyBulletProcess.h src/AttractState/GAttractState.cpp src/AttractState/GAttractState.h src/AttractState/GAttractProcess.cpp src/AttractState/GAttractProcess.h src/MainMenuState/GMainMenuState.cpp src/MainMenuState/GMainMenuState.h src/MainMenuState/GMainMenuProcess.cpp src/MainMenuState/GMainMenuProcess.h src/GameState/GNextWaveProcess.cpp src/GameState/GNextWaveProcess.h src/GameState/GBossProcess.cpp src/GameState/GBossProcess.h) ProcessorCount(N) if (NOT N EQUAL 0) - set(${PROJECT_NAME}_FLAGS -j${N}) - set(${PROJECT_NAME}_BUILD_FLAGS -j${N}) - set(${PROJECT_NAME}_args ${${PROJECT_NAME}_args} PARALLEL_LEVEL ${N}) + set(${PROJECT_NAME}_FLAGS -j${N}) + set(${PROJECT_NAME}_BUILD_FLAGS -j${N}) + set(${PROJECT_NAME}_args ${${PROJECT_NAME}_args} PARALLEL_LEVEL ${N}) endif () BUILD_COMMAND( - $(MAKE) --silent + $(MAKE) --silent ) # make Modite.app if (APPLE) - SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES MACOSX_BUNDLE TRUE) - INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ".") + SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES MACOSX_BUNDLE TRUE) + INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ".") endif (APPLE) TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${CREATIVE_ENGINE_LINK_LIBRARIES}) diff --git a/Evade2/src/AttractState/GAttractProcess.cpp b/Evade2/src/AttractState/GAttractProcess.cpp index 6bd5b5e..8af019e 100644 --- a/Evade2/src/AttractState/GAttractProcess.cpp +++ b/Evade2/src/AttractState/GAttractProcess.cpp @@ -123,19 +123,19 @@ TBool GAttractProcess::NextState() { ad->timer--; if (ad->timer < 0) { ad->screen++; - if ((game_mode == GAME_STATE_ATTRACT_MODE && ad->screen > MAX_SCREEN) || - (game_mode == GAME_STATE_CREDITS && ad->screen > MAX_CREDITS)) { + if ((game_mode == GAME_STATE_ATTRACT_MODE && ad->screen > MAX_SCREEN)) { gGame->SetState(GAME_STATE_CREDITS); return EFalse; - } else { -// Sound::play_sound(SFX_NEXT_ATTRACT_SCREEN); - InitScreen(); - mState = STATE_TYPEWRITER; - return ETrue; } - } else { - return ETrue; + if (game_mode == GAME_STATE_CREDITS && ad->screen > MAX_CREDITS) { + gGame->SetState(GAME_STATE_MAIN_MENU); + return EFalse; + } +// Sound::play_sound(SFX_NEXT_ATTRACT_SCREEN); + InitScreen(); + mState = STATE_TYPEWRITER; } + return ETrue; } TBool GAttractProcess::TypewriterState() { @@ -148,9 +148,10 @@ TBool GAttractProcess::TypewriterState() { gGame->SetState(GAME_STATE_GAME); return EFalse; } + if (gControls.WasPressed(BUTTON_START)) { ad->timer = -1; -// me->sleep(1, next); + gGame->SetState(GAME_STATE_GAME); return EFalse; } diff --git a/Evade2/src/AttractState/GAttractState.cpp b/Evade2/src/AttractState/GAttractState.cpp index d892685..7a65e72 100644 --- a/Evade2/src/AttractState/GAttractState.cpp +++ b/Evade2/src/AttractState/GAttractState.cpp @@ -14,19 +14,8 @@ GAttractState::GAttractState() : BGameEngine(gViewPort) { gGameEngine = this; mPlayfield = new GStarfield(); AddProcess(new GAttractProcess()); - GCamera::vx = GCamera::vy = 0; - GCamera::vz = 2; - - gDisplay.SetColor(COLOR_BLACK, 0,0,0); - for (TInt i=1; i<256; i++) { - gDisplay.SetColor(i, 255,255,255); - } - gDisplay.SetColor(COLOR_WHITE, 255, 255, 255); - gDisplay.SetColor(ASSAULT_COLOR, 255, 50, 50); - gDisplay.SetColor(BOMBER_COLOR, 50, 255, 50); - gDisplay.SetColor(SCOUT_COLOR, 255, 50, 255); - gDisplay.SetColor(EBULLET_COLOR, 50, 50, 255); - gDisplay.SetColor(BOMB_COLOR, 255, 255, 50); + gCamera->vx = gCamera->vy = 0; + gCamera->vz = 2; } GAttractState::~GAttractState() noexcept { diff --git a/Evade2/src/GGame.cpp b/Evade2/src/GGame.cpp index 561437c..40e1aea 100644 --- a/Evade2/src/GGame.cpp +++ b/Evade2/src/GGame.cpp @@ -7,6 +7,7 @@ // states #include "./GameState/GGameState.h" #include "./SplashState/GSplashState.h" +#include "./MainMenuState/GMainMenuState.h" #include "./AttractState/GAttractState.h" static TUint32 start; @@ -25,12 +26,10 @@ TBool GGame::mDebug = EFalse; GGame::GGame() { gGame = this; printf("Construct GGame\n"); - mWave = 1; - mKills = 0; - mDifficulty = 1; - gVectorFont = new GVectorFont(); - gGameEngine = ENull; - mState = 0; + gVectorFont = new GVectorFont(); + mDifficulty = 1; + gGameEngine = ENull; + mState = 0; SetState(GAME_STATE_SPLASH); // SetState(GAME_STATE_GAME); } @@ -58,33 +57,57 @@ TInt GGame::GetState() const { } void GGame::SetState(GAMESTATE aNewState) { - delete gGameEngine; + for (TInt i = 0; i < 256; i++) { + gDisplay.SetColor(i, 255, 255, 255); + } + + gDisplay.SetColor(COLOR_BLACK, 0, 0, 0); + gDisplay.SetColor(COLOR_WHITE, 255, 255, 255); + + gDisplay.SetColor(COLOR_STAR, 255,255,255); + + gDisplay.SetColor(ASSAULT_COLOR, 255, 50, 50); + gDisplay.SetColor(BOMBER_COLOR, 50, 255, 50); + gDisplay.SetColor(SCOUT_COLOR, 255, 50, 255); + + gDisplay.SetColor(EBULLET_COLOR, 50, 50, 255); + gDisplay.SetColor(BOMB_COLOR, 255, 255, 50); + mState = aNewState; switch (aNewState) { case GAME_STATE_SPLASH: printf("new State SPLASH\n"); + delete gGameEngine; gGameEngine = new GSplashState(); break; case GAME_STATE_ATTRACT_MODE: printf("new State ATTRACT\n"); + delete gGameEngine; gGameEngine = new GAttractState(); break; case GAME_STATE_GAME: printf("new State GAME\n"); + delete gGameEngine; gGameEngine = new GGameState(); break; case GAME_STATE_MAIN_MENU: printf("new State MAIN MENU\n"); - gGameEngine = new GGameState(); + delete gGameEngine; + gGameEngine = new GMainMenuState(); break; case GAME_STATE_VICTORY: printf("new State VICTORY\n"); + delete gGameEngine; gGameEngine = new GGameState(); break; case GAME_STATE_CREDITS: printf("new State CREDITS\n"); + delete gGameEngine; gGameEngine = new GAttractState(); break; +// case GAME_STATE_NEXT_WAVE: +// printf("new State NEXT WAVE\n"); +// break; } }; @@ -98,13 +121,15 @@ TBool GGame::IsGameState() const { void GGame::Run() { TBool done = EFalse; + while (!done) { Random(); // randomize mShmoo.Set(TUint8(mShmoo.r + 16), TUint8(mShmoo.g + 16), TUint8(mShmoo.b + 16)); gDisplay.displayBitmap->SetColor(COLOR_SHMOO, mShmoo); - GCamera::Move(); + gCamera->Move(); gGameEngine->GameLoop(); gDisplay.Update(); + if (gControls.WasPressed(BUTTONQ)) { done = ETrue; } diff --git a/Evade2/src/GGame.h b/Evade2/src/GGame.h index 97a3d06..26f9abb 100644 --- a/Evade2/src/GGame.h +++ b/Evade2/src/GGame.h @@ -12,14 +12,9 @@ class BFont; enum GAMESTATE { GAME_STATE_SPLASH, GAME_STATE_MAIN_MENU, -// GAME_STATE_LOAD_GAME, -// GAME_STATE_MAIN_OPTIONS, -// GAME_STATE_RESET_OPTIONS, GAME_STATE_ATTRACT_MODE, -// GAME_STATE_RESET_GAME, GAME_STATE_GAME, -// GAME_STATE_RESUME_GAME, -// GAME_STATE_LOAD_SAVEGAME, +// GAME_STATE_NEXT_WAVE, GAME_STATE_VICTORY, GAME_STATE_CREDITS, }; @@ -40,11 +35,7 @@ class GGame : public BApplication { TBool IsGameState() const; -public: - TUint8 mDifficulty; - TInt16 mKills; - TInt16 mWave; - + TUint8 mDifficulty; static TBool mDebug; protected: TInt mState; diff --git a/Evade2/src/Game.h b/Evade2/src/Game.h index 99eaa4b..00c643c 100644 --- a/Evade2/src/Game.h +++ b/Evade2/src/Game.h @@ -10,9 +10,11 @@ //#define SCREEN_DEPTH 8 const TFloat CAMERA_VZ = 2; // 4; +const TFloat CAMERA_WARP_VZ = 4; const TFloat DELTACONTROL = 6; // 11; const TInt8 MAX_BULLETS = 6; const TFloat BULLET_VZ = 8; // 15; +const TFloat ALERT_TOP = 30; // COLLISION_RADIUS = distance from player bullet to enemy required for a hit const TFloat COLLISION_RADIUS = 64; diff --git a/Evade2/src/GameState/GBossProcess.cpp b/Evade2/src/GameState/GBossProcess.cpp new file mode 100644 index 0000000..9c1cc8d --- /dev/null +++ b/Evade2/src/GameState/GBossProcess.cpp @@ -0,0 +1,593 @@ +// +// Created by Michael Schwartz on 11/6/20. +// + +#include "GBossProcess.h" +#include "GNextWaveProcess.h" +#include "GGameState.h" +#include "GPlayerProcess.h" +#include "GEnemyBulletProcess.h" +#include "GCamera.h" + +#include "img/boss_1_img.h" +#include "img/boss_2_img.h" +#include "img/boss_3_img.h" + +static const TFloat z_dist = 256; +static const TFloat frames = 32; + +const TInt TIMER = 240; + +enum { + WARP_STATE, + EXPLODE_STATE, + ACTION_STATE, +}; + +GBossProcess::GBossProcess() : BProcess() { + mSprite = new GVectorSprite(); + mSprite->z = gCamera->z + TIMER * 30 + 512; + mSprite->x = gCamera->x; + mSprite->y = gCamera->y; + mSprite->vx = mSprite->vy = mSprite->vz = 0; + mSprite->mState = 0; + + gGameState->AddSprite(mSprite); + mTimer = TIMER; + mState = WARP_STATE; + gGameState->mState = STATE_BOSS; + + if (gGameState->mWave % 3 == 0) { + mType = 3; + mLines = boss_3_img; + mSprite->SetLines(boss_3_img); + mSprite->x = gCamera->x - 512; + mSprite->vx = 10; + mSprite->vy = Random(-3, 3); + } else if (gGameState->mWave % 2 == 0) { + mType = 2; + mLines = boss_2_img; + mSprite->SetLines(boss_2_img); + InitOrbit(); + } else { + mType = 1; + mLines = boss_1_img; + mSprite->SetLines(boss_1_img); + mSprite->x = gCamera->x + 512; + mSprite->vx = -10; + mSprite->y = gCamera->y; + } + mHitPoints = 20 + (gGame->mDifficulty * mType); +} + +GBossProcess::~GBossProcess() { + mSprite->Remove(); + delete mSprite; +} + +TBool GBossProcess::RunBefore() { + if (gGameState->mState != STATE_PLAY) { + return ETrue; + } + return ETrue; +} + +TBool GBossProcess::Hit() { + if (mSprite->flags & OFLAG_COLLISION) { + mHitPoints--; + mSprite->flags &= ~OFLAG_COLLISION; + return ETrue; + } + return EFalse; +} + +void GBossProcess::InitOrbit() { + TBool left = Random() & 1; + TFloat angle = left ? 0 : (2 * PI); + mSprite->x = cos(angle) * 256; + mSprite->z = gCamera->z + sin(angle) * 256; + mSprite->y = gCamera->y + Random(30, 90); + mSprite->vy = Random(-6 + (gGame->mDifficulty * -1), 6 + (gGame->mDifficulty)); + mSprite->vx = 0; + mSprite->vz = -50 - (gGame->mDifficulty * 2); + mSprite->mState = left ? 0 : 180; +} + +TBool GBossProcess::WarpState() { + if (mTimer-- < 0) { + mState = ACTION_STATE; + gGameState->mState = STATE_BOSS; + gCamera->vz = CAMERA_VZ; + mSprite->vz = CAMERA_VZ; + return ETrue; + } + + gVectorFont->scale = 1.5; + gCamera->vz = 30; + gVectorFont->printf(90, ALERT_TOP, "WARP TO ACE!"); + gGameState->mPlayerProcess->recharge_shield(); + gGameState->mPlayerProcess->recharge_power(); + return ETrue; +} + +TBool GBossProcess::ExplodeState() { + const TInt16 NUM_FRAMES = 58 * 2; + mSprite->flags |= OFLAG_EXPLODE; + mSprite->mState++; + +// EBullet::genocide(); // Kill all enemy bullets + // Done exploding, move forward to the next wave + if (mSprite->mState > NUM_FRAMES) { + mState = STATE_NEXT_WAVE; + gCamera->vz = CAMERA_VZ; + + gGameState->AddProcess(new GNextWaveProcess()); + return EFalse; + } else { + return ETrue; + } +} + +void GBossProcess::EngagePlayerRandomXY() { + mSprite->z = gCamera->z + z_dist - 150; + + // Debugging stuff + // Font::scale = .7 * 256; + // Font::printf(5, 5, "%f", mSprite->x - gCamera->x); + // Font::printf(5, 15, "%f", mSprite->y - gCamera->y); + + if (mSprite->mState == 1) { + mSprite->mTheta += 5. + gGame->mDifficulty; + } else { + mSprite->mTheta -= 5. + gGame->mDifficulty; + } + // Debug + // mSprite->x = gCamera->x; + // mSprite->y = gCamera->y; + + if (--mSprite->mTimer > 0) { + return; + } + + gGameState->AddProcess(new GEnemyBulletProcess(mSprite, EBULLET_BOMB)); + mSprite->mTimer = gGameState->mWave > 20 ? 10 : (40 - gGame->mDifficulty); + // Keep within bounds of the screen + if (mSprite->x - gCamera->x < -300) { + mSprite->vx = Random(3, 10 + gGame->mDifficulty); + } else if (mSprite->x - gCamera->x > 300) { + mSprite->vx = Random(-3, -10 + gGame->mDifficulty * -1); + } else { + mSprite->vx = Random(-10 + (gGame->mDifficulty * -1), 10 + gGame->mDifficulty); + } + + if (mSprite->y - gCamera->y < -300) { + mSprite->vy = Random(3, 10 + gGame->mDifficulty); + } else if (mSprite->y - gCamera->y > 300) { + mSprite->vy = Random(-3, -10 + gGame->mDifficulty * -1); + } else { + mSprite->vy = Random(-10 + (gGame->mDifficulty * -1), 10 + gGame->mDifficulty); + } +} + +void GBossProcess::RandomizeFlee() { + mSprite->y = gCamera->y + Random(-150, 150); + mSprite->vy = Random(-7, 7); + mSprite->vx = Random(-7, 7); + mSprite->z = gCamera->z - 50; + mSprite->vz = gCamera->vz + TFloat(Random(1, 7) * gGame->mDifficulty); + mSprite->mTheta = Random(-180, 180); +} + +void GBossProcess::EngagePlayerFlee() { + if (mSprite->flags & ORBIT_LEFT) { + mSprite->mState -= gGame->mDifficulty; + if (mSprite->mState < 0) { + mSprite->mState = 0; + RandomizeFlee(); + mSprite->flags &= ~ORBIT_LEFT; + } + } else { + mSprite->mState += gGame->mDifficulty; + if (mSprite->mState > 90) { + mSprite->mState = 90; + RandomizeFlee(); + mSprite->flags |= ORBIT_LEFT; + } + } + + if (--mSprite->mTimer > 0) { + return; + } + gGameState->AddProcess(new GEnemyBulletProcess(mSprite, EBULLET_BOMB)); + + mSprite->mTimer = gGameState->mWave > 20 ? 20 : (50 - gGame->mDifficulty); + // mSprite->x = gCamera->x; + // mSprite->y = gCamera->y; + mSprite->vx += Random(-7, 7); + mSprite->vy += Random(-7, 7); +} + +void GBossProcess::EngagePlayerOrbit() { + if (mSprite->flags & ORBIT_LEFT) { + mSprite->mState -= gGame->mDifficulty; + if (mSprite->mState < 0) { + mSprite->y = gCamera->y + Random(-150, 150); + // mSprite->vy = random(-7,7); + + mSprite->mState = 0; + mSprite->flags &= ~ORBIT_LEFT; + } else { + mSprite->mTheta -= 12; + } + } else { + mSprite->mState += gGame->mDifficulty; + if (mSprite->mState > 180) { + mSprite->y = gCamera->y + Random(-150, 150); + mSprite->mState = 180; + mSprite->flags |= ORBIT_LEFT; + } else { + mSprite->mTheta += 12; + } + } + + TFloat rad = RADIANS(mSprite->mState); + mSprite->x = cos(rad) * 512; + mSprite->z = gCamera->z + sin(rad) * 512; + + if (--mSprite->mTimer <= 0) { + mSprite->mTimer = gGameState->mWave > 20 ? 20 : (50 - gGame->mDifficulty); + gGameState->AddProcess(new GEnemyBulletProcess(mSprite, EBULLET_BOMB)); + } +} + +TBool GBossProcess::ActionState() { + if (Hit()) { + if (mHitPoints <= 2) { + mSprite->flags &= OFLAG_EXPLODE; + mSprite->mState = 0; + mSprite->vz = gCamera->vz - 3; + +// Sound::play_sound(SFX_BOSS_EXPLODE); + mState = EXPLODE_STATE; + return ETrue; + } + + mSprite->SetLines(ENull); + + if (mType == 1) { + // mSprite->y = Random(-5, 5); + mSprite->mState = (mSprite->mState == 1) ? 0 : 1; + } + // else if (Boss::boss_type == 2) { + // init_orbit(o, Random() & 1); + // } + // else { + // randomize_flee(o); + // } + } else { + mSprite->SetLines(mLines); + + if (mType == 1) { + EngagePlayerRandomXY(); + } else if (mType == 2) { + EngagePlayerOrbit(); + } else { + EngagePlayerFlee(); + } + } + + return ETrue; +} + + +TBool GBossProcess::RunAfter() { + switch (mState) { + case WARP_STATE: + return WarpState(); + case EXPLODE_STATE: + return ExplodeState(); + } + return ETrue; + +// if (mTimer-- < 0) { +// gGameState->mState = STATE_BOSS; +// gCamera->vz = CAMERA_VZ; +// mSprite->vz = CAMERA_VZ; +// } else { +// } +// return ETrue; +} + +#if 0 +TUint16 Boss::hit_points = 0; +UTInt8 Boss::boss_type; + +static BOOL hit(Object *o) { + if (mSprite->flags & OFLAG_COLLISION) { + Boss::hit_points--; + mSprite->flags &= ~OFLAG_COLLISION; + return TRUE; + } + return FALSE; +} + +const TInt8 *getBossLines() { + switch (Boss::boss_type) { + case 3: + return boss_3_img; + break; + case 2: + return boss_2_img; + break; + default: + return boss_1_img; + } +} + +/** +Ideas: +instead of randomizing vx, vy, you can set y to sin(theta)*64 or something like +that (edited) [18:43] and change theta over time [18:43] it'll make it a +sinusoidal pattern +*/ + +static void engage_player_random_xy(Object *o) { + mSprite->z = gCamera->z + z_dist - 150; + + // Debugging stuff + // Font::scale = .7 * 256; + // Font::printf(5, 5, "%f", mSprite->x - gCamera->x); + // Font::printf(5, 15, "%f", mSprite->y - gCamera->y); + + if (mSprite->mState == 1) { + mSprite->theta += 5 + gGame->mDifficulty; + } else { + mSprite->theta -= 5 + gGame->mDifficulty; + } + // Debug + // mSprite->x = gCamera->x; + // mSprite->y = gCamera->y; + + if (--mSprite->timer > 0) { + return; + } + gGameState->AddProcess(new GEnemyBulletProcess(mSprite, EBULLET_BOMB)); + mSprite->timer = gGame->mWave > 20 ? 10 : (40 - gGame->mDifficulty); + // Keep within bounds of the screen + if (mSprite->x - gCamera->x < -300) { + mSprite->vx = random(3, 10 + gGame->mDifficulty); + } else if (mSprite->x - gCamera->x > 300) { + mSprite->vx = random(-3, -10 + gGame->mDifficulty * -1); + } else { + mSprite->vx = random(-10 + (gGame->mDifficulty * -1), 10 + gGame->mDifficulty); + } + + if (mSprite->y - gCamera->y < -300) { + mSprite->vy = random(3, 10 + gGame->mDifficulty); + } else if (mSprite->y - gCamera->y > 300) { + mSprite->vy = random(-3, -10 + gGame->mDifficulty * -1); + } else { + mSprite->vy = random(-10 + (gGame->mDifficulty * -1), 10 + gGame->mDifficulty); + } +} + +static void randomize_flee(Object *o) { + mSprite->y = gCamera->y + random(-150, 150); + mSprite->vy = random(-7, 7); + mSprite->vx = random(-7, 7); + mSprite->z = gCamera->z - 50; + mSprite->vz = gCamera->vz + (random(1, 7) * gGame->mDifficulty); + mSprite->theta = random(-180, 180); +} + +static void engage_player_flee(Object *o) { + + if (mSprite->flags & ORBIT_LEFT) { + mSprite->mState -= gGame->mDifficulty; + if (mSprite->mState < 0) { + mSprite->mState = 0; + randomize_flee(o); + mSprite->flags &= ~ORBIT_LEFT; + } + } else { + mSprite->mState += gGame->mDifficulty; + if (mSprite->mState > 90) { + mSprite->mState = 90; + randomize_flee(o); + mSprite->flags |= ORBIT_LEFT; + } + } + + if (--mSprite->timer > 0) { + return; + } + gGameState->AddProcess(new GEnemyBulletProcess(mSprite, EBULLET_BOMB)); + + mSprite->timer = gGame->mWave > 20 ? 20 : (50 - gGame->mDifficulty); + // mSprite->x = gCamera->x; + // mSprite->y = gCamera->y; + mSprite->vx += random(-7, 7); + mSprite->vy += random(-7, 7); +} + +// Copy of init_assault +static void init_orbit(Object *o, BOOL left) { + TFloat angle = left ? 0 : (2 * PI); + mSprite->x = cos(angle) * 256; + mSprite->z = gCamera->z + sin(angle) * 256; + mSprite->y = gCamera->y + random(30, 90); + mSprite->vy = random(-6 + (gGame->mDifficulty * -1), 6 + (gGame->mDifficulty)); + mSprite->vx = 0; + mSprite->vz = -50 - (gGame->mDifficulty * 2); + mSprite->mState = left ? 0 : 180; +} + +static void engage_player_orbit(Object *o) { + + if (mSprite->flags & ORBIT_LEFT) { + mSprite->mState -= gGame->mDifficulty; + if (mSprite->mState < 0) { + mSprite->y = gCamera->y + random(-150, 150); + // mSprite->vy = random(-7,7); + + mSprite->mState = 0; + mSprite->flags &= ~ORBIT_LEFT; + } else { + mSprite->theta -= 12; + } + } else { + mSprite->mState += gGame->mDifficulty; + if (mSprite->mState > 180) { + mSprite->y = gCamera->y + random(-150, 150); + mSprite->mState = 180; + mSprite->flags |= ORBIT_LEFT; + } else { + mSprite->theta += 12; + } + } + + TFloat rad = RADIANS(mSprite->mState); + mSprite->x = cos(rad) * 512; + mSprite->z = gCamera->z + sin(rad) * 512; + + if (--mSprite->timer <= 0) { + mSprite->timer = gGame->mWave > 20 ? 20 : (50 - gGame->mDifficulty); + gGameState->AddProcess(new GEnemyBulletProcess(mSprite, EBULLET_BOMB)); + } +} + +/** + * Boss is exploding state. + */ +void Boss::explode(Process *me, Object *o) { + const WORD NUM_FRAMES = 58; + mSprite->flags |= OFLAG_EXPLODE; + mSprite->mState++; + EBullet::genocide(); // Kill all enemy bullets + // Done exploding, move forward to the next wave + if (mSprite->mState > NUM_FRAMES) { + game_mode = MODE_NEXT_WAVE; + Game::kills = 65; + gCamera->vz = CAMERA_VZ; + Sound::play_score(NEXT_WAVE_SONG); + + ProcessManager::birth(Game::next_wave); + me->suicide(); + } else { + me->sleep(1, explode); + } +} + +void Boss::action(Process *me, Object *o) { + if (hit(o)) { + if (Boss::hit_points <= 2) { + + mSprite->flags &= OFLAG_EXPLODE; + mSprite->mState = 0; + mSprite->vz = gCamera->vz - 3; + + Sound::play_sound(SFX_BOSS_EXPLODE); + me->sleep(1, explode); + return; + } + + mSprite->lines = NULL; + + if (Boss::boss_type == 1) { + // mSprite->y = random(-5, 5); + mSprite->mState = (mSprite->mState == 1) ? 0 : 1; + } + // else if (Boss::boss_type == 2) { + // init_orbit(o, random() & 1); + // } + // else { + // randomize_flee(o); + // } + } else { + mSprite->lines = getBossLines(); + + if (Boss::boss_type == 1) { + engage_player_random_xy(o); + } else if (Boss::boss_type == 2) { + engage_player_orbit(o); + } else { + engage_player_flee(o); + } + } + + me->sleep(1); +} + +void Boss::start_action(Process *me, Object *o) { + + if (Boss::boss_type == 2) { + if (--mSprite->timer > 0) { + game_mode = MODE_GAME; + me->sleep(1, action); + } else { + me->sleep(1); + } + } else { + mSprite->y = gCamera->y; + mSprite->z = gCamera->z + z_dist; + if (Boss::boss_type == 1) { + mSprite->z = gCamera->z + z_dist - 150; + if (mSprite->x <= gCamera->x) { + game_mode = MODE_GAME; + me->sleep(1, action); + } else { + me->sleep(1); + } + } else { + if (mSprite->x > gCamera->x) { + game_mode = MODE_GAME; + me->sleep(1, action); + } else { + me->sleep(1); + } + } + } +} + +void Boss::entry(Process *me, Object *o) { + // production + game_mode = MODE_NEXT_WAVE; + Game::kills = 0; + gCamera->vz = -10; + + mSprite->set_type(OTYPE_ENEMY); + mSprite->z = gCamera->z + z_dist - 150; + + mSprite->mState = 0; + mSprite->vz = gCamera->vz; + mSprite->color = BOSS_COLOR; + + if (gGame->mWave % 3 == 0) { + Boss::boss_type = 3; + mSprite->x = gCamera->x - 512; + mSprite->vx = +10; + mSprite->vy = random(-3, 3); + Sound::play_score(STAGE_3_BOSS_SONG); + } else if (gGame->mWave % 2 == 0) { + Boss::boss_type = 2; + init_orbit(o, random() & 1); + Sound::play_score(STAGE_2_BOSS_SONG); + } else { + Boss::boss_type = 1; + mSprite->x = gCamera->x + 512; + mSprite->vx = -10; + mSprite->y = gCamera->y; + Sound::play_score(STAGE_1_BOSS_SONG); + } + + mSprite->lines = getBossLines(); + + // PRODUCTION + Boss::hit_points = 20 + (gGame->mDifficulty * Boss::boss_type); + // DEV/TEST + // Boss::hit_points = 1; + me->sleep(1, Boss::start_action); +} + + +#endif \ No newline at end of file diff --git a/Evade2/src/GameState/GBossProcess.h b/Evade2/src/GameState/GBossProcess.h new file mode 100644 index 0000000..27c5361 --- /dev/null +++ b/Evade2/src/GameState/GBossProcess.h @@ -0,0 +1,43 @@ +// +// Created by Michael Schwartz on 11/6/20. +// + +#ifndef EVADE2_GBOSSPROCESS_H +#define EVADE2_GBOSSPROCESS_H + +#include "Game.h" +#include "GVectorSprite.h" + +class GBossProcess : public BProcess { +public: + GBossProcess(); + + ~GBossProcess() OVERRIDE; + +public: + TBool RunBefore() OVERRIDE; + + TBool RunAfter() OVERRIDE; + +protected: + void InitOrbit(); + TBool Hit(); + void EngagePlayerRandomXY(); + void EngagePlayerOrbit(); + void RandomizeFlee(); + void EngagePlayerFlee(); +protected: + TBool WarpState(); + TBool ExplodeState(); + TBool ActionState(); + +protected: + GVectorSprite *mSprite; + const TInt8 *mLines; + TInt mTimer; + TInt mState; + TInt mType; + TInt mHitPoints; +}; + +#endif //EVADE2_GBOSSPROCESS_H diff --git a/Evade2/src/GameState/GEnemyBulletProcess.cpp b/Evade2/src/GameState/GEnemyBulletProcess.cpp index b44bc5d..cf90c53 100644 --- a/Evade2/src/GameState/GEnemyBulletProcess.cpp +++ b/Evade2/src/GameState/GEnemyBulletProcess.cpp @@ -12,15 +12,15 @@ GEnemyBulletProcess::GEnemyBulletProcess(GVectorSprite *enemy, TInt8 type) { const TFloat FRAMES = 90 / gGame->mDifficulty; mSprite = new GVectorSprite(STYPE_EBULLET); - mSprite->SetLines( (type == EBULLET_BOMB) ? ebomb_img : ebullet_img); + mSprite->SetLines((type == EBULLET_BOMB) ? ebomb_img : ebullet_img); mSprite->mColor = (type == EBULLET_BOMB) ? BOMB_COLOR : EBULLET_COLOR; mSprite->mTimer = 256; // timeout mSprite->x = enemy->x - 8; mSprite->y = enemy->y - 8; mSprite->z = enemy->z; - mSprite->vx = (GCamera::x - mSprite->x) / FRAMES; - mSprite->vy = (GCamera::y - mSprite->y) / FRAMES; - mSprite->vz = GCamera::vz - (mSprite->z - GCamera::z) / FRAMES; + mSprite->vx = (gCamera->x - mSprite->x) / FRAMES; + mSprite->vy = (gCamera->y - mSprite->y) / FRAMES; + mSprite->vz = gCamera->vz - (mSprite->z - gCamera->z) / FRAMES; // printf("Bullet vx,vy,vz = %f,%f,%f mState(%d)\n", mSprite->vx, mSprite->vy, mSprite->vz, mSprite->mTimer); gGameEngine->AddSprite(mSprite); } @@ -32,14 +32,18 @@ GEnemyBulletProcess::~GEnemyBulletProcess() noexcept { } TBool GEnemyBulletProcess::RunBefore() { + if (gGameState->mState != STATE_PLAY) { + return EFalse; + } mSprite->mTheta += (mSprite->GetLines() == ebomb_img) ? mSprite->x : 40; return ETrue; } TBool GEnemyBulletProcess::RunAfter() { - if (GCamera::CollidesWith(mSprite)) { + if (gCamera->CollidesWith(mSprite)) { if (gGame->IsGameState()) { gGameState->mPlayerProcess->Hit(10); + return EFalse; } } diff --git a/Evade2/src/GameState/GEnemyProcess.cpp b/Evade2/src/GameState/GEnemyProcess.cpp index 11e90ef..d326e4d 100644 --- a/Evade2/src/GameState/GEnemyProcess.cpp +++ b/Evade2/src/GameState/GEnemyProcess.cpp @@ -16,11 +16,11 @@ const TInt8 *GEnemyProcess::Graphic(TInt aType) { switch (aType) { case ENEMY_ASSAULT: - return (const TInt8 *)&enemy_assault_1_img; + return (const TInt8 *) &enemy_assault_1_img; case ENEMY_BOMBER: - return (const TInt8 *)&enemy_heavy_bomber_1_img; + return (const TInt8 *) &enemy_heavy_bomber_1_img; case ENEMY_SCOUT: - return (const TInt8 *)&enemy_scout_1_img; + return (const TInt8 *) &enemy_scout_1_img; default: Panic("Invalid enemy type: %d\n", aType); } @@ -42,7 +42,7 @@ GEnemyProcess::~GEnemyProcess() noexcept { TBool GEnemyProcess::death() { if (mSprite->flags & OFLAG_COLLISION) { - gGame->mKills++; + gGameState->mKills++; mSprite->flags &= OFLAG_EXPLODE; mSprite->mState = 0; return ETrue; @@ -51,9 +51,12 @@ TBool GEnemyProcess::death() { } void GEnemyProcess::fire() { + if (gGameState->mState != STATE_PLAY) { + return; + } mSprite->mTimer--; if (mSprite->mTimer <= 0) { - if (GCamera::vx || GCamera::vy) { + if (gCamera->vx || gCamera->vy) { mSprite->mTimer = 1; return; } @@ -85,7 +88,7 @@ void GEnemyProcess::bank(TInt16 delta) { } void GEnemyProcess::respawn() { - mSprite->mTimer = Random(gGame->mWave > 6 ? 30 : 30, 60) + 30; + mSprite->mTimer = Random(gGameState->mWave > 6 ? 30 : 30, 60) + 30; // printf("RESPAWN %d\n", mSprite->mTimer); mState = ESTATE_WAITINIT; @@ -94,8 +97,8 @@ void GEnemyProcess::respawn() { void GEnemyProcess::init_assault(TBool left) { TFloat angle = left ? 0 : (2 * PI); mSprite->x = cos(angle) * 256; - mSprite->z = GCamera::z + sin(angle) * 256; - mSprite->y = GCamera::y; // + 64 - random(0, 128); + mSprite->z = gCamera->z + sin(angle) * 256; + mSprite->y = gCamera->y; // + 64 - random(0, 128); mSprite->vx = mSprite->vy = mSprite->vz = 0; mSprite->mState = 0; mSprite->mColor = ASSAULT_COLOR; @@ -105,9 +108,9 @@ void GEnemyProcess::init_assault(TBool left) { * Initialize object for scout enemy */ void GEnemyProcess::init_scout() { - mSprite->x = GCamera::x + Random(-256, 256); - mSprite->y = GCamera::y + Random(-256, 256); - mSprite->z = GCamera::z + 1024; + mSprite->x = gCamera->x + Random(-256, 256); + mSprite->y = gCamera->y + Random(-256, 256); + mSprite->z = gCamera->z + 1024; mSprite->vz = CAMERA_VZ - 3; // 12; mSprite->vx = mSprite->vy = 0; mSprite->mTheta = Random(-50, 50); @@ -118,10 +121,10 @@ void GEnemyProcess::init_scout() { * Initialize object for bomber enemy */ void GEnemyProcess::init_bomber() { - mSprite->x = GCamera::x + 128 - Random(0, 127); - mSprite->y = GCamera::y + 128 - Random(0, 127); - mSprite->z = GCamera::z - 30; - mSprite->vz = CAMERA_VZ + 1 + gGame->mWave; + mSprite->x = gCamera->x + 128 - Random(0, 127); + mSprite->y = gCamera->y + 128 - Random(0, 127); + mSprite->z = gCamera->z - 30; + mSprite->vz = CAMERA_VZ + 1 + gGameState->mWave; mSprite->vx = mSprite->vy = 0; mSprite->mColor = BOMBER_COLOR; } @@ -133,7 +136,7 @@ void GEnemyProcess::init() { mSprite->mTheta = 0; // One enemy type enters per wave - switch (Random(0, (gGame->mWave > 3) ? 3 : gGame->mWave)) { + switch (Random(0, (gGameState->mWave > 3) ? 3 : gGameState->mWave)) { case 0: mSprite->SetLines((const TInt8 *) &enemy_scout_1_img); init_scout(); @@ -165,7 +168,7 @@ TBool GEnemyProcess::StateSeek() { // bank(o); fire(); o->mTheta += 8; - if (o->z - GCamera::z < Random(256, 512)) { + if (o->z - gCamera->z < Random(256, 512)) { o->mState = -1; mState = ESTATE_RUNAWAY; return ETrue; @@ -176,7 +179,7 @@ TBool GEnemyProcess::StateSeek() { TBool GEnemyProcess::StateEvade() { GVectorSprite *o = mSprite; - if (o->z - GCamera::z > 512) { + if (o->z - gCamera->z > 512) { o->mState = 1; mState = ESTATE_RUNAWAY; return ETrue; @@ -217,11 +220,11 @@ TBool GEnemyProcess::StateOrbit() { } TFloat rad = RADIANS(o->mState); - o->vy = (GCamera::y > o->y) ? -2 : 2; - o->y = GCamera::y; + o->vy = (gCamera->y > o->y) ? -2 : 2; + o->y = gCamera->y; o->x = cos(rad) * 256; if (gGame->GetState() == GAME_STATE_GAME) { - o->z = GCamera::z + sin(rad) * 256; + o->z = gCamera->z + sin(rad) * 256; } return ETrue; @@ -248,7 +251,7 @@ TBool GEnemyProcess::StateRunAway() { } o->vx += o->vx > 0 ? .1 : -.1; o->vy += o->vy > 0 ? .1 : -.1; - if (o->BehindCamera() || (o->z - GCamera::z) > 1024) { + if (o->BehindCamera() || (o->z - gCamera->z) > 1024) { respawn(); return ETrue; } @@ -265,12 +268,18 @@ TBool GEnemyProcess::StateExplode() { mSprite->flags |= OFLAG_EXPLODE; mSprite->mState++; if (mSprite->BehindCamera() || mSprite->mState > 50) { + if (gGameState->mState != STATE_PLAY) { + return EFalse; + } respawn(); } return ETrue; } TBool GEnemyProcess::RunBefore() { + if (gGameState->mState != STATE_PLAY) { + return EFalse; + } switch (mState) { case ESTATE_SEEK: return StateSeek(); diff --git a/Evade2/src/GameState/GGameState.cpp b/Evade2/src/GameState/GGameState.cpp index 5ad85ad..4cb73ce 100644 --- a/Evade2/src/GameState/GGameState.cpp +++ b/Evade2/src/GameState/GGameState.cpp @@ -6,35 +6,36 @@ #include "GStarfield.h" #include "GPlayerProcess.h" #include "GEnemyProcess.h" +#include "GNextWaveProcess.h" +#include "GBossProcess.h" GGameState *gGameState; GGameState::GGameState() : BGameEngine(gViewPort) { gGameEngine = this; - gGameState = this; - mPlayfield = new GStarfield(); + gGameState = this; + mState = STATE_PLAY; + mWave = 1; + mKills = 0; + mPlayfield = new GStarfield(); // set colors - gDisplay.SetColor(COLOR_BLACK, 0,0,0); - for (TInt i=1; i<256; i++) { - gDisplay.SetColor(i, 255,255,255); - } - gDisplay.SetColor(COLOR_WHITE, 255, 255, 255); - gDisplay.SetColor(ASSAULT_COLOR, 255, 50, 50); - gDisplay.SetColor(BOMBER_COLOR, 50, 255, 50); - gDisplay.SetColor(SCOUT_COLOR, 255, 50, 255); - gDisplay.SetColor(EBULLET_COLOR, 50, 50, 255); - gDisplay.SetColor(BOMB_COLOR, 255, 255, 50); AddProcess(new GEnemyProcess()); AddProcess(new GEnemyProcess()); AddProcess(new GEnemyProcess()); mPlayerProcess = new GPlayerProcess(); AddProcess(mPlayerProcess); - gDisplay.SetColor(COLOR_WHITE, 255,255,255); - gDisplay.SetColor(COLOR_STAR, 255,255,255); } GGameState::~GGameState() { // delete mPlayfield; } +void GGameState::PostRender() { + if (mState != STATE_PLAY) { + return; + } + if (mKills > (10 + mWave) * gGame->mDifficulty) { + AddProcess(new GBossProcess()); + } +} diff --git a/Evade2/src/GameState/GGameState.h b/Evade2/src/GameState/GGameState.h index c478509..320e2ad 100644 --- a/Evade2/src/GameState/GGameState.h +++ b/Evade2/src/GameState/GGameState.h @@ -7,17 +7,29 @@ #include +enum { + STATE_PLAY, + STATE_BOSS, + STATE_NEXT_WAVE, +}; + class GPlayerProcess; class GGameState : public BGameEngine { public: GGameState(); - ~GGameState(); + ~GGameState() OVERRIDE; + +public: + void PostRender() OVERRIDE; public: -// void GameLoop() OVERRIDE; GPlayerProcess *mPlayerProcess; + TInt32 mState; + TInt16 mKills; + TInt16 mWave; + }; extern GGameState *gGameState; diff --git a/Evade2/src/GameState/GNextWaveProcess.cpp b/Evade2/src/GameState/GNextWaveProcess.cpp new file mode 100644 index 0000000..7f65cb4 --- /dev/null +++ b/Evade2/src/GameState/GNextWaveProcess.cpp @@ -0,0 +1,36 @@ +// +// Created by Michael Schwartz on 11/6/20. +// + +#include "GNextWaveProcess.h" +#include "GPlayerProcess.h" +#include "GGameState.h" +#include "GCamera.h" + +GNextWaveProcess::GNextWaveProcess() : BProcess() { + mTimer = 240; + gCamera->vz = 30; + gGameState->mState = STATE_NEXT_WAVE; +} + +GNextWaveProcess::~GNextWaveProcess() noexcept { + gGameState->mState = STATE_PLAY; + gGameState->mKills = 0; + gGameState->mWave++; + if (gGameState->mWave % 4 == 0) { + gGame->mDifficulty++; + } + gCamera->vz = CAMERA_VZ; +} + +TBool GNextWaveProcess::RunBefore() { + return ETrue; +} + +TBool GNextWaveProcess::RunAfter() { + gVectorFont->scale = 1.5; + gVectorFont->printf(85, ALERT_TOP, "START WAVE %d", gGameState->mWave + 1); + gGameState->mPlayerProcess->recharge_shield(); + gGameState->mPlayerProcess->recharge_power(); + return --mTimer > 0; +} \ No newline at end of file diff --git a/Evade2/src/GameState/GNextWaveProcess.h b/Evade2/src/GameState/GNextWaveProcess.h new file mode 100644 index 0000000..185a6a3 --- /dev/null +++ b/Evade2/src/GameState/GNextWaveProcess.h @@ -0,0 +1,25 @@ +// +// Created by Michael Schwartz on 11/6/20. +// + +#ifndef EVADE2_GNEXTWAVEPROCESS_H +#define EVADE2_GNEXTWAVEPROCESS_H + +#include "Game.h" + +class GNextWaveProcess : public BProcess { +public: + GNextWaveProcess(); + + ~GNextWaveProcess(); + +public: + TBool RunBefore(); + + TBool RunAfter(); +protected: + TInt mTimer; +}; + + +#endif //EVADE2_GNEXTWAVEPROCESS_H diff --git a/Evade2/src/GameState/GPlayerBulletProcess.cpp b/Evade2/src/GameState/GPlayerBulletProcess.cpp index 9a9ca26..96dc6ad 100644 --- a/Evade2/src/GameState/GPlayerBulletProcess.cpp +++ b/Evade2/src/GameState/GPlayerBulletProcess.cpp @@ -12,19 +12,19 @@ GPlayerBulletProcess::GPlayerBulletProcess(TFloat deltaX, TFloat deltaY, TBool alt) { mSprite = new GVectorSprite(STYPE_PBULLET); if (alt) { - mSprite->x = GCamera::x + 28; - mSprite->y = GCamera::y - 28; - mSprite->z = GCamera::z; + mSprite->x = gCamera->x + 28; + mSprite->y = gCamera->y - 28; + mSprite->z = gCamera->z; mSprite->mState = 20; } else { - mSprite->x = GCamera::x - 28; - mSprite->y = GCamera::y - 28; - mSprite->z = GCamera::z; + mSprite->x = gCamera->x - 28; + mSprite->y = gCamera->y - 28; + mSprite->z = gCamera->z; mSprite->mState = -20; } mSprite->vx = deltaX; mSprite->vy = deltaY; - mSprite->vz = GCamera::vz + BULLET_VZ; + mSprite->vz = gCamera->vz + BULLET_VZ; mSprite->SetLines(bullet_img); gGameEngine->AddSprite(mSprite); } @@ -42,7 +42,7 @@ TBool GPlayerBulletProcess::RunBefore() { } TBool GPlayerBulletProcess::RunAfter() { - if (mSprite->z - GCamera::z > 512) { + if (mSprite->z - gCamera->z > 512) { return EFalse; } BSpriteList &l = gGameState->mSpriteList; diff --git a/Evade2/src/GameState/GPlayerProcess.cpp b/Evade2/src/GameState/GPlayerProcess.cpp index 4c57505..25e6c48 100644 --- a/Evade2/src/GameState/GPlayerProcess.cpp +++ b/Evade2/src/GameState/GPlayerProcess.cpp @@ -26,7 +26,7 @@ const TUint8 crosshair_right_4x8[] = { GPlayerProcess::GPlayerProcess() { color = COLOR_WHITE; - GCamera::vz = CAMERA_VZ; + gCamera->vz = CAMERA_VZ; power = MAX_POWER; shield = MAX_LIFE; mNumBullets = 0; @@ -124,7 +124,7 @@ void GPlayerProcess::recharge_power() { TBool GPlayerProcess::RunBefore() { if (gGame->GetState() != GAME_STATE_GAME) { // if (game_mode != MODE_GAME) { - GCamera::vx = GCamera::vy = 0; + gCamera->vx = gCamera->vy = 0; return ETrue; } @@ -149,16 +149,16 @@ TBool GPlayerProcess::RunBefore() { if (gControls.IsPressed(CONTROL_BURST)) { if (power > 0) { - GCamera::vz = CAMERA_VZ * 2; + gCamera->vz = CAMERA_WARP_VZ; power--; if (power < 0) { power = 0; } } else { - GCamera::vz = CAMERA_VZ; + gCamera->vz = CAMERA_VZ; } } else { - GCamera::vz = CAMERA_VZ; + gCamera->vz = CAMERA_VZ; power++; if (power > MAX_POWER) { power = MAX_POWER; @@ -166,19 +166,19 @@ TBool GPlayerProcess::RunBefore() { } if (gControls.IsPressed(CONTROL_JOYRIGHT)) { - GCamera::vx = -DELTACONTROL; + gCamera->vx = -DELTACONTROL; } else if (gControls.IsPressed(CONTROL_JOYLEFT)) { - GCamera::vx = DELTACONTROL; + gCamera->vx = DELTACONTROL; } else { - GCamera::vx = 0; + gCamera->vx = 0; } if (gControls.IsPressed(CONTROL_JOYDOWN)) { - GCamera::vy = DELTACONTROL; + gCamera->vy = DELTACONTROL; } else if (gControls.IsPressed(CONTROL_JOYUP)) { - GCamera::vy = -DELTACONTROL; + gCamera->vy = -DELTACONTROL; } else { - GCamera::vy = 0; + gCamera->vy = 0; } return ETrue; } diff --git a/Evade2/src/MainMenuState/GMainMenu.cpp b/Evade2/src/MainMenuState/GMainMenu.cpp deleted file mode 100644 index fe91034..0000000 --- a/Evade2/src/MainMenuState/GMainMenu.cpp +++ /dev/null @@ -1,12 +0,0 @@ -// -// Created by Michael Schwartz on 11/4/20. -// - -#include "GMainMenu.h" -#include "GStarfield.h" - -GMainMenu::GMainMenu() : BGameEngine(gViewPort) { - mPlayfield = new GStarfield(); -} - -GMainMenu::~GMainMenu() noexcept {} \ No newline at end of file diff --git a/Evade2/src/MainMenuState/GMainMenu.h b/Evade2/src/MainMenuState/GMainMenu.h deleted file mode 100644 index 5c52ac5..0000000 --- a/Evade2/src/MainMenuState/GMainMenu.h +++ /dev/null @@ -1,18 +0,0 @@ -// -// Created by Michael Schwartz on 11/4/20. -// - -#ifndef EVADE2_GMAINMENU_H -#define EVADE2_GMAINMENU_H - -#include "Game.h" - -class GMainMenu : public BGameEngine { -public: - GMainMenu(); - - ~GMainMenu() OVERRIDE; -}; - - -#endif //EVADE2_GMAINMENU_H diff --git a/Evade2/src/MainMenuState/GMainMenuProcess.cpp b/Evade2/src/MainMenuState/GMainMenuProcess.cpp index 18c15df..3a70c3b 100644 --- a/Evade2/src/MainMenuState/GMainMenuProcess.cpp +++ b/Evade2/src/MainMenuState/GMainMenuProcess.cpp @@ -3,3 +3,47 @@ // #include "GMainMenuProcess.h" +#include "GCamera.h" + +GMainMenuProcess::GMainMenuProcess() : BProcess() { +// gCamera->vx = 0; +// gCamera->vy = 0; +// gCamera->vz = CAMERA_VZ; + mTimer = 280 * 2; + mTheta = 90; +} + +GMainMenuProcess::~GMainMenuProcess() noexcept {} + +TBool GMainMenuProcess::RunAfter() { + gVectorFont->scale = 4; + gVectorFont->color = COLOR_SHMOO; + gVectorFont->print_string_rotatedx(70, 90, mTheta, "EVADE2"); + gVectorFont->color = COLOR_WHITE; + + mTimer--; + gVectorFont->scale = 1; + if (mTimer & 32) { + gVectorFont->scale = 2; + gVectorFont->printf(130, 155, "START"); + } + + mTheta += 5; + if (mTheta > 90 + 360 * 2) { + mTheta = 90 + 360 * 2; + } + + return ETrue; +} + +TBool GMainMenuProcess::RunBefore() { + if (gControls.WasPressed(BUTTON_START)) { + gGame->SetState(GAME_STATE_GAME); + return EFalse; + } + if (mTimer < 0 || gControls.WasPressed(BUTTONA|BUTTONB)) { + gGame->SetState(GAME_STATE_ATTRACT_MODE); + return EFalse; + } + return ETrue; +} diff --git a/Evade2/src/MainMenuState/GMainMenuProcess.h b/Evade2/src/MainMenuState/GMainMenuProcess.h index 56ed2d0..935f130 100644 --- a/Evade2/src/MainMenuState/GMainMenuProcess.h +++ b/Evade2/src/MainMenuState/GMainMenuProcess.h @@ -18,6 +18,9 @@ class GMainMenuProcess : public BProcess { TBool RunAfter(); +protected: + TFloat mTheta; + TInt32 mTimer; }; diff --git a/Evade2/src/MainMenuState/GMainMenuState.cpp b/Evade2/src/MainMenuState/GMainMenuState.cpp new file mode 100644 index 0000000..fc98a9d --- /dev/null +++ b/Evade2/src/MainMenuState/GMainMenuState.cpp @@ -0,0 +1,18 @@ +// +// Created by Michael Schwartz on 11/4/20. +// + +#include "GMainMenuState.h" +#include "GMainMenuProcess.h" +#include "GStarfield.h" +#include "GCamera.h" + +GMainMenuState::GMainMenuState() : BGameEngine(gViewPort) { +// gGameEngine = this; + mPlayfield = new GStarfield(); + gCamera->vx = gCamera->vy = 0; + gCamera->vz = CAMERA_VZ; + AddProcess(new GMainMenuProcess()); +} + +GMainMenuState::~GMainMenuState() noexcept {} \ No newline at end of file diff --git a/Evade2/src/MainMenuState/GMainMenuState.h b/Evade2/src/MainMenuState/GMainMenuState.h new file mode 100644 index 0000000..edccfd3 --- /dev/null +++ b/Evade2/src/MainMenuState/GMainMenuState.h @@ -0,0 +1,18 @@ +// +// Created by Michael Schwartz on 11/4/20. +// + +#ifndef EVADE2_GMAINMENUSTATE_H +#define EVADE2_GMAINMENUSTATE_H + +#include "Game.h" + +class GMainMenuState : public BGameEngine { +public: + GMainMenuState(); + + ~GMainMenuState() OVERRIDE; +}; + + +#endif //EVADE2_GMAINMENUSTATE_H diff --git a/Evade2/src/SplashState/GSplashProcess.cpp b/Evade2/src/SplashState/GSplashProcess.cpp index 5a797bc..dcdbaea 100644 --- a/Evade2/src/SplashState/GSplashProcess.cpp +++ b/Evade2/src/SplashState/GSplashProcess.cpp @@ -65,7 +65,7 @@ void GSplashProcess::RenderText() { TBool GSplashProcess::RunAfter() { if (gControls.WasPressed(BUTTON_ANY)) { // } || --mTimer <= 0) { - gGame->SetState(GAME_STATE_ATTRACT_MODE); + gGame->SetState(GAME_STATE_MAIN_MENU); #ifdef ENABLE_AUDIO gSoundPlayer.SfxStartGame(); diff --git a/Evade2/src/common/GCamera.cpp b/Evade2/src/common/GCamera.cpp index f2fee77..d81c2c5 100644 --- a/Evade2/src/common/GCamera.cpp +++ b/Evade2/src/common/GCamera.cpp @@ -1,58 +1,15 @@ #include "GCamera.h" -// -// -// +GCamera *gCamera; -TFloat GCamera::x = 0; -TFloat GCamera::y = 0; -TFloat GCamera::z = 0; +GCamera::GCamera() { + x = 0; + y = 0; + z = 0; -TFloat GCamera::vx = 0; -TFloat GCamera::vy = 0; -TFloat GCamera::vz = CAMERA_VZ; + vx = 0; + vy = 0; + vz = CAMERA_VZ; +} -// -//Camera::Camera() { -// mX = mY = mZ = 0; -// mVX = mVY = mVZ = 0; -//} -// -//public: -// static TFloat mX, mY, mZ; -// static TFloat mVX, mVY, mVZ; -// -// static void Move() { -// mX += mVX; -// mY += mVY; -// mZ += mVZ; -// } -// -//}; -//extern Camera *gCamera; - -//TFloat Camera::mX = 0; -//TFloat Camera::mY = 0; -//TFloat Camera::mZ = 0; -// -//TFloat Camera::mVX = 0; -//TFloat Camera::mVY = 0; -//TFloat Camera::mVZ = 0; -// -// -//void Camera::Move() { -// Camera::mX += Camera::mVX; -// Camera::mY += Camera::mVY; -// Camera::mZ += Camera::mVZ; -//} -//// -//TBool Camera::CollidesWith(GVectorSprite *aVSprite) { -// // If enemy bullet collides with player -// if (abs(aVSprite->mZ - Camera::mZ) < abs(aVSprite->mVZ) && abs(aVSprite->mX - Camera::mX) < 64 && abs(aVSprite->mY - Camera::mY) < 64) { -// return ETrue; -// } -// return EFalse; -//} -// -//extern Camera *gCamera; diff --git a/Evade2/src/common/GCamera.h b/Evade2/src/common/GCamera.h index 8253006..39be235 100644 --- a/Evade2/src/common/GCamera.h +++ b/Evade2/src/common/GCamera.h @@ -6,25 +6,28 @@ class GCamera { public: - static TFloat x,y,z; - static TFloat vx,vy,vz; + GCamera(); public: - static void Move() { - GCamera::x += GCamera::vx; - GCamera::y += GCamera::vy; - GCamera::z += GCamera::vz; + TFloat x, y, z; + TFloat vx, vy, vz; + +public: + void Move() { + x += vx; + y += vy; + z += vz; } - static TBool CollidesWith(GVectorSprite *aVSprite) { + TBool CollidesWith(GVectorSprite *aVSprite) const { // If enemy bullet collides with player - if (abs(aVSprite->z - GCamera::z) < abs(aVSprite->vz) && abs(aVSprite->x - GCamera::x) < 64 && abs(aVSprite->y - GCamera::y) < 64) { + if (abs(aVSprite->z - z) < abs(aVSprite->vz) && abs(aVSprite->x - x) < 64 && abs(aVSprite->y - y) < 64) { return ETrue; } return EFalse; } }; - +extern GCamera *gCamera; #endif diff --git a/Evade2/src/common/GStarfield.cpp b/Evade2/src/common/GStarfield.cpp index b7cf405..72b1713 100644 --- a/Evade2/src/common/GStarfield.cpp +++ b/Evade2/src/common/GStarfield.cpp @@ -6,6 +6,7 @@ #include "GCamera.h" GStarfield::GStarfield() : BPlayfield() { + gCamera = new GCamera(); for (TInt i = 0; i < NUM_STARS; i++) { InitStar(i); } @@ -17,7 +18,7 @@ GStarfield::~GStarfield() noexcept { void GStarfield::Render() { gDisplay.renderBitmap->Clear(0); - TFloat cz = GCamera::z, + TFloat cz = gCamera->z, sw = TFloat(SCREEN_WIDTH), sh = TFloat(SCREEN_HEIGHT); @@ -29,8 +30,8 @@ void GStarfield::Render() { } TFloat ratioX = sw / (zz + sw); TFloat ratioY = sh / (zz + sh); - TFloat x = (sw / 2) - (mStarX[i] - GCamera::x) * ratioX; - TFloat y = (sh / 2) - (mStarY[i] - GCamera::y) * ratioY; + TFloat x = (sw / 2) - (mStarX[i] - gCamera->x) * ratioX; + TFloat y = (sh / 2) - (mStarY[i] - gCamera->y) * ratioY; if (x < 0) { // printf("InitStar x %f < 0\n", x); @@ -51,7 +52,7 @@ void GStarfield::Render() { } void GStarfield::InitStar(TInt aIndex) { - mStarX[aIndex] = TFloat(256) - Random(0, 512) + GCamera::x; - mStarY[aIndex] = TFloat(256) - Random(0, 512) + GCamera::y; - mStarZ[aIndex] = GCamera::z + Random(200, 512); + mStarX[aIndex] = TFloat(256) - Random(0, 512) + gCamera->x; + mStarY[aIndex] = TFloat(256) - Random(0, 512) + gCamera->y; + mStarZ[aIndex] = gCamera->z + Random(200, 512); } \ No newline at end of file diff --git a/Evade2/src/common/GVectorFont.cpp b/Evade2/src/common/GVectorFont.cpp index 32f307f..3c15082 100644 --- a/Evade2/src/common/GVectorFont.cpp +++ b/Evade2/src/common/GVectorFont.cpp @@ -11,6 +11,7 @@ #include "charset.h" GVectorFont *gVectorFont; + // constructor GVectorFont::GVectorFont() { scale = 1.0; @@ -20,7 +21,7 @@ GVectorFont::GVectorFont() { #ifdef ENABLE_ROTATING_TEXT TInt16 GVectorFont::print_string_rotatedx(TFloat x, TFloat y, TFloat theta, const char *s) { - theta = float(theta) * 3.1415926 / 180; + theta = TFloat(theta) * 3.1415926 / 180; TFloat cost = cos(theta), sint = sin(theta); const char *p = s; @@ -29,9 +30,9 @@ TInt16 GVectorFont::print_string_rotatedx(TFloat x, TFloat y, TFloat theta, cons TInt16 xo = x; while (char c = *p++) { - auto *glyph = (const TInt16 *)charset[toupper(c) - 32]; + auto *glyph = (const TInt8 *)charset[toupper(c) - 32]; if (glyph) { - TInt16 lines = *glyph++; + TInt8 lines = *glyph++; for (TInt16 i = 0; i < lines; i++) { TFloat x0 = *glyph++ * scale + x, diff --git a/Evade2/src/common/GVectorSprite.cpp b/Evade2/src/common/GVectorSprite.cpp index 7714cea..f069138 100644 --- a/Evade2/src/common/GVectorSprite.cpp +++ b/Evade2/src/common/GVectorSprite.cpp @@ -78,20 +78,20 @@ TFloat GVectorSprite::DistanceTo(GVectorSprite *aOther) { }; TBool GVectorSprite::Render(BViewPort *aViewPort) { - if (!mLines || z <= GCamera::z) { + if (!mLines || z <= gCamera->z) { // nothing to draw return EFalse; } - TFloat zz = (z - GCamera::z) * 2; + TFloat zz = (z - gCamera->z) * 2; TFloat ratio = 128 / (zz + 128); TFloat sw = TFloat(SCREEN_WIDTH), sh = TFloat(SCREEN_HEIGHT); bool isEnemy = type == STYPE_ENEMY; // printf("is enemy = %i\n", isEnemy); - TFloat cx = (GCamera::x - x) * ratio + sw / 2; - TFloat cy = (GCamera::y - y) * ratio + sh / 2; + TFloat cx = (gCamera->x - x) * ratio + sw / 2; + TFloat cy = (gCamera->y - y) * ratio + sh / 2; // uint8_t color = isEnemy ? 5 : 255; @@ -102,8 +102,8 @@ TBool GVectorSprite::Render(BViewPort *aViewPort) { if ((!drawn) && isEnemy) { // draw radar blip - TFloat dx = GCamera::x - x, - dy = GCamera::y - y, + TFloat dx = gCamera->x - x, + dy = gCamera->y - y, angle = atan2(dy, dx), midx = sw / 2, midy = sh / 2, @@ -129,5 +129,5 @@ TBool GVectorSprite::Render(BViewPort *aViewPort) { TBool GVectorSprite::BehindCamera() { - return z <= GCamera::z; + return z <= gCamera->z; } \ No newline at end of file