2023-02-19 00:08:37 -05:00
/**
* Furnace Tracker - multi - system chiptune tracker
2024-01-16 21:26:57 -05:00
* Copyright ( C ) 2021 - 2024 tildearrow and contributors
2023-02-19 00:08:37 -05:00
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License along
* with this program ; if not , write to the Free Software Foundation , Inc . ,
* 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA .
*/
# include "gui.h"
2023-02-26 04:21:27 -05:00
# include "../ta-log.h"
2023-02-28 02:06:39 -05:00
# include "IconsFontAwesome4.h"
2023-03-07 01:21:07 -05:00
# include "imgui_internal.h"
2023-02-19 00:08:37 -05:00
2024-04-01 00:35:59 -04:00
# include "gif_load.h"
2023-02-25 18:04:17 -05:00
# define TS FurnaceGUITutorialStep
2024-04-01 01:44:42 -04:00
# ifdef _WIN32
# include <windows.h>
# include "../utfutils.h"
# else
2024-04-01 00:35:59 -04:00
# include <dirent.h>
# endif
enum FurnaceCVObjectTypes {
CV_NULL = 0 ,
CV_PLAYER ,
CV_BULLET ,
CV_ENEMY_BULLET ,
CV_BOMB ,
CV_ENEMY_BOMB ,
CV_EXPLOSION ,
CV_ENEMY ,
CV_FURBALL ,
CV_MINE ,
CV_POWERUP_P ,
CV_POWERUP_S ,
CV_EXTRA_LIFE
} ;
struct FurnaceCVObject {
FurnaceCV * cv ;
unsigned short type ;
unsigned short spriteDef [ 512 ] ;
unsigned char spriteWidth , spriteHeight ;
bool dead ;
short x , y ;
unsigned char z , prio ;
short collX0 , collX1 , collY0 , collY1 ;
virtual void collision ( FurnaceCVObject * other ) ;
virtual void tick ( ) ;
FurnaceCVObject ( FurnaceCV * p ) :
cv ( p ) ,
type ( 0 ) ,
spriteWidth ( 2 ) ,
spriteHeight ( 2 ) ,
dead ( false ) ,
x ( 0 ) ,
y ( 0 ) ,
z ( 0 ) ,
prio ( 1 ) ,
collX0 ( 0 ) ,
collX1 ( 15 ) ,
collY0 ( 0 ) ,
collY1 ( 15 ) {
memset ( spriteDef , 0 , 512 * sizeof ( unsigned short ) ) ;
spriteDef [ 0 ] = 4 ;
spriteDef [ 1 ] = 5 ;
spriteDef [ 2 ] = 36 ;
spriteDef [ 3 ] = 37 ;
}
virtual ~ FurnaceCVObject ( ) {
}
} ;
void FurnaceCVObject : : collision ( FurnaceCVObject * other ) {
}
void FurnaceCVObject : : tick ( ) {
}
struct FurnaceCVPlayer : FurnaceCVObject {
short subX , subY ;
short speedX , speedY ;
unsigned char shootDir ;
unsigned char animFrame ;
unsigned char invincible ;
unsigned char shotTimer ;
void collision ( FurnaceCVObject * other ) ;
void tick ( ) ;
FurnaceCVPlayer ( FurnaceCV * p ) :
FurnaceCVObject ( p ) ,
subX ( 0 ) ,
subY ( 0 ) ,
speedX ( 0 ) ,
speedY ( 0 ) ,
shootDir ( 2 ) ,
animFrame ( 0 ) ,
invincible ( 120 ) ,
shotTimer ( 4 ) {
type = CV_PLAYER ;
spriteWidth = 3 ;
spriteHeight = 3 ;
spriteDef [ 0 ] = 0x10 ;
spriteDef [ 1 ] = 0x11 ;
spriteDef [ 2 ] = 0x12 ;
spriteDef [ 3 ] = 0x30 ;
spriteDef [ 4 ] = 0x31 ;
spriteDef [ 5 ] = 0x32 ;
spriteDef [ 6 ] = 0x50 ;
spriteDef [ 7 ] = 0x51 ;
spriteDef [ 8 ] = 0x52 ;
collX0 = 0 ;
collX1 = 23 ;
collY0 = 0 ;
collY1 = 23 ;
}
} ;
struct FurnaceCVBullet : FurnaceCVObject {
short subX , subY ;
short speedX , speedY ;
unsigned char bulletType , orient , life ;
void killBullet ( ) ;
void setType ( unsigned char t ) ;
void collision ( FurnaceCVObject * other ) ;
void tick ( ) ;
FurnaceCVBullet ( FurnaceCV * p ) :
FurnaceCVObject ( p ) ,
subX ( 0 ) ,
subY ( 0 ) ,
speedX ( 0 ) ,
speedY ( 0 ) ,
bulletType ( 0 ) ,
orient ( 0 ) ,
life ( 0 ) {
type = CV_BULLET ;
spriteWidth = 1 ;
spriteHeight = 1 ;
spriteDef [ 0 ] = 6 ;
collX0 = 2 ;
collX1 = 5 ;
collY0 = 2 ;
collY1 = 5 ;
}
} ;
struct FurnaceCVEnemyBullet : FurnaceCVObject {
short subX , subY ;
short speedX , speedY ;
unsigned char animFrame , bulletType ;
void setType ( unsigned char type ) ;
void tick ( ) ;
FurnaceCVEnemyBullet ( FurnaceCV * p ) :
FurnaceCVObject ( p ) ,
subX ( 0 ) ,
subY ( 0 ) ,
speedX ( 0 ) ,
speedY ( 0 ) ,
animFrame ( rand ( ) & 0xff ) ,
bulletType ( 0 ) {
type = CV_ENEMY_BULLET ;
spriteWidth = 1 ;
spriteHeight = 1 ;
spriteDef [ 0 ] = 6 ;
collX0 = 2 ;
collX1 = 5 ;
collY0 = 2 ;
collY1 = 5 ;
}
} ;
struct FurnaceCVEnemy1 : FurnaceCVObject {
unsigned char enemyType ;
unsigned char health ;
unsigned char orient ;
unsigned char stopped ;
unsigned char animFrame ;
short nextTime , shootTime ;
unsigned char shootCooldown ;
void collision ( FurnaceCVObject * other ) ;
void tick ( ) ;
void setType ( unsigned char type ) ;
FurnaceCVEnemy1 ( FurnaceCV * p ) :
FurnaceCVObject ( p ) ,
enemyType ( 0 ) ,
health ( 1 ) ,
orient ( rand ( ) & 3 ) ,
stopped ( 0 ) ,
animFrame ( 0 ) ,
nextTime ( 64 + ( rand ( ) % 600 ) ) ,
shootTime ( 8 ) ,
shootCooldown ( 0 ) {
type = CV_ENEMY ;
spriteDef [ 0 ] = 0x200 ;
spriteDef [ 1 ] = 0x201 ;
spriteDef [ 2 ] = 0x220 ;
spriteDef [ 3 ] = 0x221 ;
}
} ;
struct FurnaceCVEnemyVortex : FurnaceCVObject {
unsigned char stopped ;
unsigned char animFrame ;
short nextTime , shootTime , speedX , speedY ;
void collision ( FurnaceCVObject * other ) ;
void tick ( ) ;
FurnaceCVEnemyVortex ( FurnaceCV * p ) :
FurnaceCVObject ( p ) ,
stopped ( 0 ) ,
animFrame ( 0 ) ,
nextTime ( 4 + ( rand ( ) % 140 ) ) ,
shootTime ( 360 ) ,
speedX ( ( rand ( ) % 5 ) - 2 ) ,
speedY ( ( rand ( ) % 5 ) - 2 ) {
type = CV_ENEMY ;
spriteDef [ 0 ] = 0x480 ;
spriteDef [ 1 ] = 0x481 ;
spriteDef [ 2 ] = 0x4a0 ;
spriteDef [ 3 ] = 0x4a1 ;
}
} ;
struct FurnaceCVExplTiny : FurnaceCVObject {
unsigned char animFrame ;
void tick ( ) ;
FurnaceCVExplTiny ( FurnaceCV * p ) :
FurnaceCVObject ( p ) ,
animFrame ( 0 ) {
type = CV_EXPLOSION ;
spriteWidth = 1 ;
spriteHeight = 1 ;
spriteDef [ 0 ] = 8 ;
}
} ;
struct FurnaceCVExplMedium : FurnaceCVObject {
unsigned char animFrame ;
void tick ( ) ;
FurnaceCVExplMedium ( FurnaceCV * p ) :
FurnaceCVObject ( p ) ,
animFrame ( 0 ) {
type = CV_EXPLOSION ;
spriteWidth = 3 ;
spriteHeight = 3 ;
spriteDef [ 0 ] = 0x210 ;
spriteDef [ 1 ] = 0x211 ;
spriteDef [ 2 ] = 0x212 ;
spriteDef [ 3 ] = 0x230 ;
spriteDef [ 4 ] = 0x231 ;
spriteDef [ 5 ] = 0x232 ;
spriteDef [ 6 ] = 0x250 ;
spriteDef [ 7 ] = 0x251 ;
spriteDef [ 8 ] = 0x252 ;
}
} ;
struct FurnaceCVFurBallMedium : FurnaceCVObject {
unsigned char animFrame ;
void tick ( ) ;
FurnaceCVFurBallMedium ( FurnaceCV * p ) :
FurnaceCVObject ( p ) ,
animFrame ( 0 ) {
type = CV_FURBALL ;
spriteWidth = 3 ;
spriteHeight = 3 ;
spriteDef [ 0 ] = 0x410 ;
spriteDef [ 1 ] = 0x411 ;
spriteDef [ 2 ] = 0x412 ;
spriteDef [ 3 ] = 0x430 ;
spriteDef [ 4 ] = 0x431 ;
spriteDef [ 5 ] = 0x432 ;
spriteDef [ 6 ] = 0x450 ;
spriteDef [ 7 ] = 0x451 ;
spriteDef [ 8 ] = 0x452 ;
}
} ;
struct FurnaceCVFurBallLarge : FurnaceCVObject {
unsigned char animFrame ;
void tick ( ) ;
FurnaceCVFurBallLarge ( FurnaceCV * p ) :
FurnaceCVObject ( p ) ,
animFrame ( 0 ) {
type = CV_FURBALL ;
spriteWidth = 4 ;
spriteHeight = 4 ;
spriteDef [ 0 ] = 0x390 ;
spriteDef [ 1 ] = 0x391 ;
spriteDef [ 2 ] = 0x392 ;
spriteDef [ 3 ] = 0x393 ;
spriteDef [ 4 ] = 0x3b0 ;
spriteDef [ 5 ] = 0x3b1 ;
spriteDef [ 6 ] = 0x3b2 ;
spriteDef [ 7 ] = 0x3b3 ;
spriteDef [ 8 ] = 0x3d0 ;
spriteDef [ 9 ] = 0x3d1 ;
spriteDef [ 10 ] = 0x3d2 ;
spriteDef [ 11 ] = 0x3d3 ;
spriteDef [ 12 ] = 0x3f0 ;
spriteDef [ 13 ] = 0x3f1 ;
spriteDef [ 14 ] = 0x3f2 ;
spriteDef [ 15 ] = 0x3f3 ;
}
} ;
struct FurnaceCVMine : FurnaceCVObject {
void collision ( FurnaceCVObject * other ) ;
FurnaceCVMine ( FurnaceCV * p ) :
FurnaceCVObject ( p ) {
type = CV_MINE ;
}
} ;
struct FurnaceCVPowerupP : FurnaceCVObject {
unsigned char life ;
void collision ( FurnaceCVObject * other ) ;
void tick ( ) ;
FurnaceCVPowerupP ( FurnaceCV * p ) :
FurnaceCVObject ( p ) ,
life ( 255 ) {
type = CV_POWERUP_P ;
}
} ;
struct FurnaceCVPowerupS : FurnaceCVObject {
unsigned char life ;
void collision ( FurnaceCVObject * other ) ;
void tick ( ) ;
FurnaceCVPowerupS ( FurnaceCV * p ) :
FurnaceCVObject ( p ) ,
life ( 255 ) {
type = CV_POWERUP_S ;
}
} ;
struct FurnaceCVExtraLife : FurnaceCVObject {
unsigned char life ;
void collision ( FurnaceCVObject * other ) ;
void tick ( ) ;
FurnaceCVExtraLife ( FurnaceCV * p ) :
FurnaceCVObject ( p ) ,
life ( 255 ) {
type = CV_EXTRA_LIFE ;
}
} ;
struct FurnaceCV {
SDL_Surface * surface ;
unsigned char * prioBuf ;
DivEngine * e ;
unsigned char * tileData ;
// state
unsigned short * curStage ;
int stageWidth , stageHeight ;
const char * typeAddr ;
unsigned char typeDelay ;
int typeX , typeY ;
int typeXStart , typeYStart ;
int typeXEnd , typeYEnd ;
int textWait , curText , transWait ;
int ticksToInit ;
bool inGame , inTransition , newHiScore , playSongs , pleaseInitSongs ;
unsigned char lives , respawnTime , stage , shotType ;
int score ;
int hiScore ;
short lastPlayerX , lastPlayerY ;
short fxChanBase , fxInsBase ;
// graphics
unsigned short tile0 [ 56 ] [ 80 ] ;
unsigned short tile1 [ 56 ] [ 80 ] ;
unsigned short scrollX [ 2 ] ;
unsigned short scrollY [ 2 ] ;
unsigned char bgColor ;
std : : vector < FurnaceCVObject * > sprite ;
// this offset is applied to sprites.
int viewX , viewY ;
// input
unsigned char joyInputPrev ;
unsigned char joyPressed ;
unsigned char joyReleased ;
unsigned char joyInput ;
template < typename T > T * createObject ( short x = 0 , short y = 0 ) ;
void buildStage ( int which ) ;
void putText ( int fontBase , bool fontHeight , String text , int x , int y ) ;
void startTyping ( const char * text , int x , int y ) ;
void soundEffect ( int ins , int chan , int note ) ;
void stopSoundEffect ( int ins , int chan , int note ) ;
void addScore ( int amount ) ;
void typeTick ( ) ;
void rasterH ( int scanline ) ;
void render ( unsigned char joyIn ) ;
void tileDataRead ( struct GIF_WHDR * data ) ;
void loadInstruments ( ) ;
bool init ( DivEngine * eng ) ;
void unload ( ) ;
FurnaceCV ( ) :
surface ( NULL ) ,
e ( NULL ) ,
tileData ( NULL ) ,
curStage ( NULL ) ,
stageWidth ( 0 ) ,
stageHeight ( 0 ) ,
typeAddr ( NULL ) ,
typeDelay ( 0 ) ,
typeX ( 0 ) ,
typeY ( 0 ) ,
typeXStart ( 0 ) ,
typeYStart ( 0 ) ,
typeXEnd ( 39 ) ,
typeYEnd ( 27 ) ,
textWait ( 60 ) ,
curText ( 0 ) ,
transWait ( 0 ) ,
ticksToInit ( 2 ) ,
inGame ( false ) ,
inTransition ( false ) ,
newHiScore ( false ) ,
playSongs ( true ) ,
pleaseInitSongs ( false ) ,
lives ( 3 ) ,
respawnTime ( 0 ) ,
stage ( 0 ) ,
shotType ( 0 ) ,
score ( 0 ) ,
hiScore ( 25000 ) ,
lastPlayerX ( 0 ) ,
lastPlayerY ( 0 ) ,
fxChanBase ( - 1 ) ,
fxInsBase ( - 1 ) ,
bgColor ( 0 ) ,
viewX ( 0 ) ,
viewY ( 0 ) ,
joyInputPrev ( 0 ) ,
joyPressed ( 0 ) ,
joyReleased ( 0 ) ,
joyInput ( 0 ) {
memset ( tile0 , 0 , 80 * 56 * sizeof ( short ) ) ;
memset ( tile1 , 0 , 80 * 56 * sizeof ( short ) ) ;
scrollX [ 0 ] = 0 ;
scrollX [ 1 ] = 0 ;
scrollY [ 0 ] = 0 ;
scrollY [ 1 ] = 0 ;
}
} ;
static const char * cvText [ ] = {
// intro
" Play demo songs? \n "
2024-04-01 01:44:42 -04:00
" - Down: Play current song \n "
" - Up: Play demo songs " ,
2024-04-01 00:35:59 -04:00
" Well, well, well. You wanna \n "
" enable Serious Mode, right? \n " ,
" Sure, if you can beat the \n "
" high score in this boring game. \n " ,
" A. D. 2xxx \n "
" April 1st \n " ,
" The plot is left \n "
2024-04-01 01:44:42 -04:00
" as an exercise for the player. \n \n "
" X - Shoot Arrow Key - Move " ,
2024-04-01 00:35:59 -04:00
" GAME OVER " ,
" Conglaturation! \n "
" \n "
" With high score beat, it \n "
" enables Serious Mode. \n "
" The User is now peace. " ,
" Restart Furnace to apply \n "
" changes. " ,
" Restart Furnace to apply \n "
" changes. " ,
" Restart Furnace to apply \n "
" changes. " ,
" Restart Furnace to apply \n "
" changes. " ,
" Restart Furnace to apply \n "
" changes. " ,
" Never gonna give STOP posting \n "
" about Rick Astley " ,
" I'M TIRED OF SEEING IT " ,
" My friends on TikTok rickroll \n "
" me " ,
" On Discord's fucking rickroll " ,
" I was in a server. Right? " ,
" And AAAAALLL of the channels \n "
" are just Never Gonna Give You Up. " ,
" I've searched for Half-Life 3 \n "
" and the video I watched it and \n "
" I said: Hey Babe, Never Gonna \n "
" Give You Up HAHA " ,
" Diiiiiiiing Diiiiiiiiiiiing \n "
" Diiing Diiiiiiing Diiiiiiiiiing \n "
" Didididiiiiiiiing " ,
" I fucking looked at the DefleMask \n "
" 1.2 teaser trailer and I said \n "
" That's a rickroll " ,
" I've looked at my [REDACTED], \n "
" I think of the scientist and I go \n "
" [REDACTED], more like never gonna \n "
" [REDACTED] up \n " ,
" AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA " ,
// this is totally intentional. do not attempt to fix it.
( const char * ) 1
} ;
2023-02-25 18:04:17 -05:00
void FurnaceGUI : : initTutorial ( ) {
tutorials [ GUI_TUTORIAL_OVERVIEW ] = FurnaceGUITutorialDef ( " Overview " , {
2023-03-01 19:19:09 -05:00
TS (
" hello! this is the Furnace tutorial! \n "
" I will teach you how to use Furnace. \n "
" if you wish to skip these tutorials, click on one of the Skip buttons. otherwise, click the " ICON_FA_CHEVRON_RIGHT " icon to continue. "
) ,
TS (
" Furnace is a chiptune tracker! \n "
" in a tracker, the song is written down in patterns, which are lists of notes, instruments and effects to play. \n "
" a playhead scrolls down through these patterns, and plays the notes that are written in them as it moves. \n "
" think of it as a piano roll, but replace the dots in the position of notes with note names (e.g. A-4). "
) ,
TS (
" these are called \" patterns \" because they may appear more than once in the song. \n "
" this is useful for (in example) percussion, avoiding duplication. \n "
" the order in which these patterns appear is determined by an order list which also scrolls down as the playhead moves between patterns. "
) ,
TS (
2023-03-07 01:21:07 -05:00
" this is the Pattern window. it displays a pattern (which contains the notes and stuff). " ,
- 1 ,
[ this ] ( ) {
highlightWindow ( " Pattern " ) ;
2023-03-07 04:14:23 -05:00
} ,
[ this ] ( ) {
nextWindow = GUI_WINDOW_PATTERN ;
2023-03-07 01:21:07 -05:00
}
2023-03-01 19:19:09 -05:00
) ,
TS (
2023-03-07 04:14:23 -05:00
" this is the Orders window. it displays which patterns are going to play. " ,
- 1 ,
[ this ] ( ) {
highlightWindow ( " Orders " ) ;
} ,
[ this ] ( ) {
nextWindow = GUI_WINDOW_ORDERS ;
}
2023-03-01 19:19:09 -05:00
) ,
TS (
2023-03-07 04:14:23 -05:00
" this is the Instruments window. it shows a list of instruments (sounds) in the song. " ,
- 1 ,
[ this ] ( ) {
highlightWindow ( " Instruments " ) ;
} ,
[ this ] ( ) {
nextWindow = GUI_WINDOW_INS_LIST ;
}
2023-03-01 19:19:09 -05:00
) ,
TS (
2023-03-07 04:14:23 -05:00
" this is the Song Information window, which allows you to change some song properties. " ,
- 1 ,
[ this ] ( ) {
2023-03-08 04:19:00 -05:00
highlightWindow ( " Song Info##Song Information " ) ;
2023-03-07 04:14:23 -05:00
} ,
[ this ] ( ) {
nextWindow = GUI_WINDOW_SONG_INFO ;
}
2023-03-01 19:19:09 -05:00
) ,
TS (
2023-03-07 04:14:23 -05:00
" this is the Speed window, which contains speed parameters. " ,
- 1 ,
[ this ] ( ) {
highlightWindow ( " Speed " ) ;
} ,
[ this ] ( ) {
nextWindow = GUI_WINDOW_SPEED ;
}
2023-03-01 19:19:09 -05:00
) ,
TS (
" and here are the Play Controls. you can use these to play the song and do some other things. \n "
2023-03-07 04:14:23 -05:00
" now that I am done explaining the interface, let's make a song! " ,
- 1 ,
[ this ] ( ) {
highlightWindow ( " Play Controls " ) ;
} ,
[ this ] ( ) {
nextWindow = GUI_WINDOW_EDIT_CONTROLS ;
}
2023-03-01 19:19:09 -05:00
) ,
TS (
" we'll start by creating an instrument. \n "
" while it's possible to work without instruments, we would be stuck with the default sound! \n "
" so let's create one... for that you click on the " ICON_FA_PLUS " button in the Instruments window. "
) ,
TS (
" "
) ,
TS (
" now let's type in some notes! \n "
" first, enable Edit Mode with the Space key. \n "
" after that, click on the pattern editor to focus it (the first empty column to be specific). \n "
) ,
TS (
" the keyboard layout for inserting notes resembles that of a piano: \n "
" - Z-M: low octave \n "
" - Q-U: mid octave \n "
" - I-P and beyond: high octave \n "
" the keys one row above the mentioned octaves are the upper keys of a piano. \n "
" let's press some of these keys to insert notes! "
) ,
TS (
" "
) ,
TS (
" and now, let's play the song! hit Enter to play it (and press it while playing to stop). "
) ,
TS (
" "
) ,
TS (
" great! \n "
" by the way, you can move around the pattern view using the arrow keys or by clicking in the pattern. "
) ,
TS (
" now let me teach you about these columns in the pattern editor. \n "
" each big column represents a channel. \n "
" a channel consists of five (or more) smaller columns: \n "
" - the first column contains notes. \n "
" - the second one represents the instruments to play (these will be filled in automatically when you have an instrument selected). \n "
" - the third one has volume changes (will explain these later). \n "
" - the last two ones are effects and effect values (you can have multiple effect columns, but that's something I will be covering later as well.) \n "
" the instrument, volume and effect columns are continuous. this means that if nothing is specified, the last value will be used. "
) ,
TS (
" let's add some volume changes to show you what I mean. "
) ,
TS (
" "
) ,
TS (
" as you can hear, volume changes affects all notes which are placed next to, or after it. \n "
" let's place some bass notes. "
) ,
TS (
" "
) ,
TS (
" oh wait! the keyboard layout only contains 2 octaves! \n "
" however, we can change the octave range by using the Octave setting in the play/edit controls. "
) ,
TS (
" "
) ,
TS (
" now let's type in the notes... "
) ,
TS (
" "
) ,
TS (
" ...and play this? "
) ,
TS (
" "
) ,
TS (
" cool, huh? but we're running out of space here. \n "
" let's expand the song. "
) ,
TS (
" for that we go in the Orders window, which contains the order these patterns will appear in. \n "
2023-03-03 02:08:28 -05:00
" the first column is position while the other columns contain pattern numbers of every channel. "
) ,
TS (
" clicking on the " ICON_FA_PLUS " button adds one row to the orders... "
2023-03-03 02:32:18 -05:00
) ,
2023-03-03 02:08:28 -05:00
TS (
" "
) ,
TS (
" and then clicking on a cell of the first column takes us there. "
) ,
TS (
" "
) ,
TS (
" now let's add more to the song. "
) ,
TS (
" "
) ,
TS (
" and after that, let's hear it! \n "
" note that playing the song by pressing Enter will play from the current position in the Orders view - that is, order 1! \n "
" we want to play from order 0 (the first order), so we go back to it first and then hit Enter. "
) ,
TS (
" "
) ,
TS (
" congratulations! you made it \n "
" what else? "
2023-03-01 19:19:09 -05:00
)
2023-02-25 18:04:17 -05:00
} ) ;
}
2023-02-19 00:08:37 -05:00
void FurnaceGUI : : syncTutorial ( ) {
2023-02-25 20:01:33 -05:00
// tutorial.userComesFrom=e->getConfInt("tutUserComesFrom",0);
2023-02-19 00:08:37 -05:00
tutorial . introPlayed = e - > getConfBool ( " tutIntroPlayed " , false ) ;
2023-05-24 05:19:45 -04:00
tutorial . protoWelcome = e - > getConfBool ( " tutProtoWelcome2 " , false ) ;
2023-02-19 00:08:37 -05:00
}
void FurnaceGUI : : commitTutorial ( ) {
2023-02-25 20:01:33 -05:00
// e->setConf("tutUserComesFrom",tutorial.userComesFrom);
2023-02-19 00:08:37 -05:00
e - > setConf ( " tutIntroPlayed " , tutorial . introPlayed ) ;
2023-05-24 05:19:45 -04:00
e - > setConf ( " tutProtoWelcome2 " , tutorial . protoWelcome ) ;
2023-02-25 20:01:33 -05:00
}
void FurnaceGUI : : activateTutorial ( FurnaceGUITutorials which ) {
2023-05-24 05:19:45 -04:00
/*
if ( tutorial . protoWelcome & & ! tutorial . taken [ which ] & & ! ImGui : : IsPopupOpen ( ( const char * ) NULL , ImGuiPopupFlags_AnyPopupId | ImGuiPopupFlags_AnyPopupLevel ) & & curTutorial = = - 1 & & introPos > = 10.0 ) {
2023-02-26 04:21:27 -05:00
logV ( " activating tutorial %d. " , which ) ;
2023-02-25 20:01:33 -05:00
curTutorial = which ;
curTutorialStep = 0 ;
}
2023-05-24 05:19:45 -04:00
*/
2023-02-24 04:19:39 -05:00
}
2024-04-01 00:35:59 -04:00
void FurnaceGUI : : initRandomDemoSong ( ) {
std : : vector < String > subDirs ;
# if !defined(IS_MOBILE) && defined(FURNACE_DATADIR) && defined(SHOW_OPEN_ASSETS_MENU_ENTRY)
String demoPath = FURNACE_DATADIR ;
demoPath + = DIR_SEPARATOR_STR ;
demoPath + = " demos " ;
# else
# ifdef IS_MOBILE
String demoPath = " /storage/emulated/0/demos " ;
# else
String demoPath = " demos " ;
# endif
# endif
logW ( " searching for demos in %s... " , demoPath ) ;
# ifdef _WIN32
WIN32_FIND_DATAW de ;
2024-04-01 01:44:42 -04:00
String realDemoPath = demoPath ;
realDemoPath + = DIR_SEPARATOR_STR ;
realDemoPath + = " * " ;
HANDLE d = FindFirstFileW ( utf8To16 ( realDemoPath . c_str ( ) ) . c_str ( ) , & de ) ;
2024-04-01 00:35:59 -04:00
if ( d = = INVALID_HANDLE_VALUE ) {
2024-04-01 01:44:42 -04:00
realDemoPath = " .. " ;
realDemoPath + = DIR_SEPARATOR_STR ;
realDemoPath + = " demos " ;
realDemoPath + = DIR_SEPARATOR_STR ;
realDemoPath + = " * " ;
2024-04-01 00:35:59 -04:00
logW ( " OH NO " ) ;
2024-04-01 01:44:42 -04:00
HANDLE d = FindFirstFileW ( utf8To16 ( realDemoPath . c_str ( ) ) . c_str ( ) , & de ) ;
2024-04-01 00:35:59 -04:00
if ( d = = INVALID_HANDLE_VALUE ) {
logW ( " dang it " ) ;
return ;
}
}
do {
String u8Name = utf16To8 ( de . cFileName ) ;
if ( u8Name = = " . " ) continue ;
if ( u8Name = = " .. " ) continue ;
if ( de . dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {
String newPath = demoPath ;
newPath + = DIR_SEPARATOR_STR ;
newPath + = u8Name ;
logW ( " adding subdir %s " , newPath ) ;
subDirs . push_back ( newPath ) ;
} else if ( strstr ( u8Name . c_str ( ) , " .fur " ) ! = NULL ) {
String newPath = demoPath ;
newPath + = DIR_SEPARATOR_STR ;
newPath + = u8Name ;
randomDemoSong . push_back ( newPath ) ;
}
} while ( FindNextFileW ( d , & de ) ! = 0 ) ;
FindClose ( d ) ;
# else
DIR * d = opendir ( demoPath . c_str ( ) ) ;
if ( d = = NULL ) {
demoPath = " .. " ;
demoPath + = DIR_SEPARATOR_STR ;
demoPath + = " demos " ;
logW ( " OH NO " ) ;
d = opendir ( demoPath . c_str ( ) ) ;
if ( d = = NULL ) {
logW ( " dang it " ) ;
return ;
}
}
struct dirent * de = NULL ;
while ( true ) {
de = readdir ( d ) ;
if ( de = = NULL ) break ;
if ( strcmp ( de - > d_name , " . " ) = = 0 ) continue ;
if ( strcmp ( de - > d_name , " .. " ) = = 0 ) continue ;
if ( de - > d_type = = DT_DIR ) {
String newPath = demoPath ;
newPath + = DIR_SEPARATOR_STR ;
newPath + = de - > d_name ;
logW ( " adding subdir %s " , newPath ) ;
subDirs . push_back ( newPath ) ;
} else if ( de - > d_type = = DT_REG & & strstr ( de - > d_name , " .fur " ) ! = NULL ) {
String newPath = demoPath ;
newPath + = DIR_SEPARATOR_STR ;
newPath + = de - > d_name ;
randomDemoSong . push_back ( newPath ) ;
}
}
closedir ( d ) ;
# endif
for ( String & i : subDirs ) {
# ifdef _WIN32
WIN32_FIND_DATAW de1 ;
2024-04-01 01:44:42 -04:00
String realI = i ;
realI + = DIR_SEPARATOR_STR ;
realI + = " *.fur " ;
HANDLE d1 = FindFirstFileW ( utf8To16 ( realI . c_str ( ) ) . c_str ( ) , & de1 ) ;
2024-04-01 00:35:59 -04:00
if ( d1 = = INVALID_HANDLE_VALUE ) continue ;
do {
2024-04-01 04:02:30 -04:00
String u8Name = utf16To8 ( de1 . cFileName ) ;
2024-04-01 01:44:42 -04:00
String newPath = i ;
2024-04-01 00:35:59 -04:00
newPath + = DIR_SEPARATOR_STR ;
newPath + = u8Name ;
randomDemoSong . push_back ( newPath ) ;
2024-04-01 04:02:30 -04:00
} while ( FindNextFileW ( d1 , & de1 ) ! = 0 ) ;
2024-04-01 00:35:59 -04:00
FindClose ( d1 ) ;
# else
DIR * d1 = opendir ( i . c_str ( ) ) ;
if ( d1 = = NULL ) continue ;
struct dirent * de1 = NULL ;
while ( true ) {
de1 = readdir ( d1 ) ;
if ( de1 = = NULL ) break ;
if ( strcmp ( de1 - > d_name , " . " ) = = 0 ) continue ;
if ( strcmp ( de1 - > d_name , " .. " ) = = 0 ) continue ;
if ( de1 - > d_type = = DT_REG & & strstr ( de1 - > d_name , " .fur " ) ! = NULL ) {
String newPath = i ;
newPath + = DIR_SEPARATOR_STR ;
newPath + = de1 - > d_name ;
randomDemoSong . push_back ( newPath ) ;
}
}
closedir ( d1 ) ;
# endif
}
}
bool FurnaceGUI : : loadRandomDemoSong ( ) {
if ( randomDemoSong . empty ( ) ) return false ;
String which = randomDemoSong [ rand ( ) % randomDemoSong . size ( ) ] ;
logW ( " RDS LOAD... %s " , which ) ;
load ( which ) ;
return true ;
}
2023-02-24 04:19:39 -05:00
void FurnaceGUI : : drawTutorial ( ) {
2023-02-25 20:01:33 -05:00
// welcome
2023-05-24 05:19:45 -04:00
if ( ! tutorial . protoWelcome ) {
2023-02-24 04:19:39 -05:00
ImGui : : OpenPopup ( " Welcome " ) ;
}
if ( ImGui : : BeginPopupModal ( " Welcome " , NULL , ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar ) ) {
ImGui : : PushFont ( bigFont ) ;
ImGui : : SetCursorPosX ( ( ImGui : : GetContentRegionAvail ( ) . x - ImGui : : CalcTextSize ( " Welcome! " ) . x ) * 0.5 ) ;
ImGui : : Text ( " Welcome! " ) ;
ImGui : : PopFont ( ) ;
2023-02-24 05:09:29 -05:00
ImGui : : Text ( " welcome to Furnace, the biggest open-source chiptune tracker! " ) ;
2023-05-24 05:19:45 -04:00
ImGui : : Separator ( ) ;
ImGui : : TextWrapped ( " here are some tips to get you started: " ) ;
ImGui : : TextWrapped (
" - add an instrument by clicking on + in Instruments \n "
" - click on the pattern view to focus it \n "
" - channel columns have the following, in this order: note, instrument, volume and effects \n "
" - hit space bar while on the pattern to toggle Edit Mode \n "
" - click on the pattern or use arrow keys to move the cursor \n "
" - values (instrument, volume, effects and effect values) are in hexadecimal \n "
" - hit enter to play/stop the song \n "
" - extend the song by adding more orders in the Orders window \n "
" - click on the Orders matrix to change the patterns of a channel (left click increases; right click decreases) "
) ;
ImGui : : TextWrapped (
" if you need help, you may: \n "
2023-10-01 16:28:55 -04:00
" - read the manual (a file called manual.pdf) \n "
2023-10-26 18:33:01 -04:00
" - ask for help in Discussions (https://github.com/tildearrow/furnace/discussions), the Furnace Discord (https://discord.gg/EfrwT2wq7z) or Furnace in Revolt (official: https://rvlt.gg/GRPS6tmc) "
2023-05-24 05:19:45 -04:00
) ;
ImGui : : Separator ( ) ;
2023-02-24 05:09:29 -05:00
2024-02-11 18:36:38 -05:00
ImGui : : TextWrapped ( " if you find any issues, be sure to report them! the issue tracker is here: https://github.com/tildearrow/furnace/issues " ) ;
2023-02-24 05:09:29 -05:00
2024-02-11 18:36:38 -05:00
if ( ImGui : : Button ( " OK " ) ) {
2023-05-24 05:19:45 -04:00
tutorial . protoWelcome = true ;
2023-02-24 04:19:39 -05:00
commitTutorial ( ) ;
ImGui : : CloseCurrentPopup ( ) ;
}
2023-02-25 20:01:33 -05:00
2023-02-24 04:19:39 -05:00
ImGui : : SetWindowPos ( ImVec2 (
( canvasW - ImGui : : GetWindowSize ( ) . x ) * 0.5 ,
( canvasH - ImGui : : GetWindowSize ( ) . y ) * 0.5
) ) ;
ImGui : : EndPopup ( ) ;
}
2023-02-25 20:01:33 -05:00
// tutorial
if ( curTutorial > = 0 & & curTutorial < GUI_TUTORIAL_MAX ) {
2023-03-07 04:14:23 -05:00
FurnaceGUITutorialStep & step = tutorials [ curTutorial ] . steps [ curTutorialStep ] ;
2023-03-07 19:23:17 -05:00
ImGui : : SetNextWindowPos ( ImVec2 ( 0 , 0 ) ) ;
ImGui : : SetNextWindowSize ( ImVec2 ( canvasW , canvasH ) ) ;
if ( ImGui : : Begin ( " Tutorial " , NULL , ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDocking ) ) {
2023-03-08 04:19:00 -05:00
ImDrawList * dl = ImGui : : GetWindowDrawList ( ) ;
2023-03-07 19:23:17 -05:00
if ( step . run ! = NULL ) {
step . run ( ) ;
} else {
ImU32 col = ImGui : : GetColorU32 ( uiColors [ GUI_COLOR_MODAL_BACKDROP ] ) ;
dl - > AddRectFilled (
ImVec2 ( 0 , 0 ) ,
ImVec2 ( canvasW , canvasH ) ,
col
) ;
}
if ( step . text [ 0 ] ) {
ImVec2 avail = ImGui : : GetContentRegionAvail ( ) ;
ImVec2 textSize = ImGui : : CalcTextSize ( step . text , NULL , false , avail . x ) ;
2023-03-08 04:19:00 -05:00
textSize . x + = ImGui : : GetStyle ( ) . WindowPadding . y * 2.0f ;
textSize . y + = ImGui : : GetStyle ( ) . WindowPadding . y * 2.0f + ImGui : : GetFrameHeightWithSpacing ( ) ;
2023-03-07 19:23:17 -05:00
if ( textSize . x > avail . x ) textSize . x = avail . x ;
if ( textSize . y > avail . y ) textSize . y = avail . y ;
ImGui : : SetCursorPos ( ImVec2 (
( canvasW - textSize . x ) * 0.5 ,
( canvasH - textSize . y ) * 0.5
) ) ;
2023-03-08 04:19:00 -05:00
dl - > AddRectFilled (
ImGui : : GetCursorPos ( ) ,
ImVec2 (
ImGui : : GetCursorPos ( ) . x + textSize . x ,
ImGui : : GetCursorPos ( ) . y + textSize . y
) ,
ImGui : : GetColorU32 ( ImGuiCol_PopupBg )
) ;
if ( ImGui : : BeginChild ( " TutText " , textSize , true , ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse ) ) {
2023-03-07 19:23:17 -05:00
ImGui : : TextWrapped ( " %s " , step . text ) ;
2023-02-28 02:06:39 -05:00
2023-03-08 04:19:00 -05:00
if ( ImGui : : Button ( " Skip " ) ) {
tutorial . taken [ curTutorial ] = true ;
curTutorial = - 1 ;
curTutorialStep = 0 ;
}
ImGui : : SameLine ( ) ;
2023-03-07 19:23:17 -05:00
if ( ImGui : : Button ( ICON_FA_CHEVRON_RIGHT ) ) {
curTutorialStep + + ;
if ( step . runAfter ! = NULL ) step . runAfter ( ) ;
if ( curTutorialStep > = ( int ) tutorials [ curTutorial ] . steps . size ( ) ) {
tutorial . taken [ curTutorial ] = true ;
curTutorial = - 1 ;
curTutorialStep = 0 ;
} else {
if ( tutorials [ curTutorial ] . steps [ curTutorialStep ] . runBefore ) tutorials [ curTutorial ] . steps [ curTutorialStep ] . runBefore ( ) ;
}
2023-03-07 04:14:23 -05:00
}
2023-02-28 02:06:39 -05:00
}
2023-03-07 19:23:17 -05:00
ImGui : : EndChild ( ) ;
2023-02-28 02:06:39 -05:00
}
2023-02-25 20:01:33 -05:00
}
2023-03-07 19:23:17 -05:00
ImGui : : End ( ) ;
2023-02-25 20:01:33 -05:00
}
2024-04-01 00:35:59 -04:00
if ( cvOpen ) {
ImGui : : SetNextWindowPos ( ImVec2 ( 0 , 0 ) ) ;
ImGui : : SetNextWindowSize ( ImVec2 ( canvasW , canvasH ) ) ;
if ( ImGui : : Begin ( " Combat Vehicle " , & cvOpen , ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_Modal | ImGuiWindowFlags_NoTitleBar ) ) {
ImVec2 dpadLoc = ImVec2 ( canvasW * 0.25 , canvasH * 0.85 ) ;
ImVec2 buttonLoc = ImVec2 ( canvasW * 0.75 , canvasH * 0.85 ) ;
float oneUnit = canvasW * 0.15 ;
ImVec2 dpadUpStart = ImVec2 (
dpadLoc . x - oneUnit * 1.5 ,
dpadLoc . y - oneUnit * 1.5
) ;
ImVec2 dpadUpEnd = ImVec2 (
dpadLoc . x + oneUnit * 1.5 ,
dpadLoc . y - oneUnit * 0.5
) ;
ImVec2 dpadLeftEnd = ImVec2 (
dpadLoc . x - oneUnit * 0.5 ,
dpadLoc . y + oneUnit * 1.5
) ;
ImVec2 dpadDownStart = ImVec2 (
dpadLoc . x - oneUnit * 1.5 ,
dpadLoc . y + oneUnit * 0.5
) ;
ImVec2 dpadDownEnd = ImVec2 (
dpadLoc . x + oneUnit * 1.5 ,
dpadLoc . y + oneUnit * 1.5
) ;
ImVec2 dpadRightStart = ImVec2 (
dpadLoc . x + oneUnit * 0.5 ,
dpadLoc . y - oneUnit * 1.5
) ;
ImVec2 buttonBStart = ImVec2 (
buttonLoc . x - oneUnit * 1.25 ,
buttonLoc . y - oneUnit * 0.5
) ;
ImVec2 buttonBEnd = ImVec2 (
buttonLoc . x - oneUnit * 0.25 ,
buttonLoc . y + oneUnit * 0.5
) ;
ImVec2 buttonAStart = ImVec2 (
buttonLoc . x + oneUnit * 0.25 ,
buttonLoc . y - oneUnit * 0.5
) ;
ImVec2 buttonAEnd = ImVec2 (
buttonLoc . x + oneUnit * 1.25 ,
buttonLoc . y + oneUnit * 0.5
) ;
unsigned char touchControls = 0 ;
if ( mobileUI ) {
for ( TouchPoint & i : activePoints ) {
// B
if ( i . x > = buttonBStart . x & & i . y > = buttonBStart . y & &
i . x < = buttonBEnd . x & & i . y < = buttonBEnd . y ) {
touchControls | = 1 ;
}
// A
if ( i . x > = buttonAStart . x & & i . y > = buttonAStart . y & &
i . x < = buttonAEnd . x & & i . y < = buttonAEnd . y ) {
touchControls | = 2 ;
}
// up
if ( i . x > = dpadUpStart . x & & i . y > = dpadUpStart . y & &
i . x < = dpadUpEnd . x & & i . y < = dpadUpEnd . y ) {
touchControls | = 16 ;
}
// down
if ( i . x > = dpadDownStart . x & & i . y > = dpadDownStart . y & &
i . x < = dpadDownEnd . x & & i . y < = dpadDownEnd . y ) {
touchControls | = 32 ;
}
// left
if ( i . x > = dpadUpStart . x & & i . y > = dpadUpStart . y & &
i . x < = dpadLeftEnd . x & & i . y < = dpadLeftEnd . y ) {
touchControls | = 64 ;
}
// right
if ( i . x > = dpadRightStart . x & & i . y > = dpadRightStart . y & &
i . x < = dpadDownEnd . x & & i . y < = dpadDownEnd . y ) {
touchControls | = 128 ;
}
}
}
if ( cv = = NULL ) {
initRandomDemoSong ( ) ;
cv = new FurnaceCV ;
cv - > init ( e ) ;
cv - > hiScore = cvHiScore ;
e - > setNumTimesPlayed ( - 1 ) ;
shaderEditor = false ;
}
if ( cvTex = = NULL ) {
cvTex = rend - > createTexture ( true , 320 , 224 , false ) ;
}
if ( cv - > pleaseInitSongs ) {
cv - > pleaseInitSongs = false ;
if ( cv - > playSongs ) {
if ( loadRandomDemoSong ( ) ) {
cv - > loadInstruments ( ) ;
}
}
}
WAKE_UP ;
if ( cv - > inTransition & & cv - > transWait = = 1 ) {
// load random demo song
if ( cv - > playSongs ) {
if ( loadRandomDemoSong ( ) ) {
cv - > loadInstruments ( ) ;
e - > changeSongP ( 0 ) ;
e - > setOrder ( 0 ) ;
e - > play ( ) ;
}
}
}
cv - > render ( touchControls ) ;
if ( cv - > hiScore > cvHiScore ) {
cvHiScore = cv - > hiScore ;
}
if ( cvTex ! = NULL ) {
SDL_LockSurface ( cv - > surface ) ;
rend - > updateTexture ( cvTex , cv - > surface - > pixels , 320 * 4 ) ;
SDL_UnlockSurface ( cv - > surface ) ;
ImDrawList * dl = ImGui : : GetForegroundDrawList ( ) ;
ImVec2 p0 , p1 ;
if ( ( ( double ) canvasH / ( double ) canvasW ) > 0.7 ) {
if ( mobileUI ) {
p0 = ImVec2 ( 0.0 , 0.0 ) ;
p1 = ImVec2 ( canvasW , canvasW * 0.7 ) ;
} else {
p0 = ImVec2 ( 0.0 , ( canvasH - ( canvasW * 0.7 ) ) * 0.5 ) ;
p1 = ImVec2 ( canvasW , canvasW * 0.7 + ( canvasH - ( canvasW * 0.7 ) ) * 0.5 ) ;
}
} else {
p0 = ImVec2 ( ( canvasW - ( canvasH / 0.7 ) ) * 0.5 , 0.0 ) ;
p1 = ImVec2 ( ( canvasH / 0.7 ) + ( canvasW - ( canvasH / 0.7 ) ) * 0.5 , canvasH ) ;
}
dl - > AddRectFilled ( ImVec2 ( 0 , 0 ) , ImVec2 ( canvasW , canvasH ) , 0xff000000 ) ;
dl - > AddImage ( rend - > getTextureID ( cvTex ) , p0 , p1 ) ;
if ( mobileUI ) {
dl - > AddRect ( dpadUpStart , dpadUpEnd , 0xff0000ff , 0 , 0 , dpiScale ) ;
dl - > AddRect ( dpadUpStart , dpadLeftEnd , 0xff00ffff , 0 , 0 , dpiScale ) ;
dl - > AddRect ( dpadDownStart , dpadDownEnd , 0xff00ff00 , 0 , 0 , dpiScale ) ;
dl - > AddRect ( dpadRightStart , dpadDownEnd , 0xffff0000 , 0 , 0 , dpiScale ) ;
dl - > AddRect ( buttonBStart , buttonBEnd , 0xffffff00 , 0 , 0 , dpiScale ) ;
dl - > AddRect ( buttonAStart , buttonAEnd , 0xffff00ff , 0 , 0 , dpiScale ) ;
}
}
}
ImGui : : End ( ) ;
if ( ImGui : : IsKeyPressed ( ImGuiKey_Escape ) ) {
time_t timet = time ( NULL ) ;
struct tm * curtm = localtime ( & timet ) ;
if ( curtm ! = NULL ) {
if ( curtm - > tm_mon = = 3 & & curtm - > tm_mday = = 1 ) {
if ( cvHiScore > 25000 ) {
if ( cv ! = NULL ) {
cv - > unload ( ) ;
delete cv ;
cv = NULL ;
}
cvOpen = false ;
}
} else {
if ( cv ! = NULL ) {
cv - > unload ( ) ;
delete cv ;
cv = NULL ;
}
cvOpen = false ;
}
} else {
if ( cv ! = NULL ) {
cv - > unload ( ) ;
delete cv ;
cv = NULL ;
}
cvOpen = false ;
}
}
}
2023-02-24 05:09:29 -05:00
}
2023-02-25 18:04:17 -05:00
2023-03-07 01:21:07 -05:00
// helper functions
void FurnaceGUI : : highlightWindow ( const char * winName ) {
2023-03-07 19:23:17 -05:00
ImDrawList * dl = ImGui : : GetWindowDrawList ( ) ;
2023-03-07 01:21:07 -05:00
ImU32 col = ImGui : : GetColorU32 ( uiColors [ GUI_COLOR_MODAL_BACKDROP ] ) ;
ImGuiWindow * win = ImGui : : FindWindowByName ( winName ) ;
if ( win ! = NULL ) {
ImVec2 start = win - > Pos ;
ImVec2 end = ImVec2 (
start . x + win - > Size . x ,
start . y + win - > Size . y
) ;
dl - > AddRectFilled (
ImVec2 ( 0 , 0 ) ,
ImVec2 ( start . x , canvasH ) ,
col
) ;
dl - > AddRectFilled (
ImVec2 ( start . x , 0 ) ,
ImVec2 ( canvasW , start . y ) ,
col
) ;
dl - > AddRectFilled (
ImVec2 ( end . x , start . y ) ,
ImVec2 ( canvasW , canvasH ) ,
col
) ;
dl - > AddRectFilled (
ImVec2 ( start . x , end . y ) ,
ImVec2 ( end . x , canvasH ) ,
col
) ;
dl - > AddRect ( start , end , ImGui : : GetColorU32 ( uiColors [ GUI_COLOR_TEXT ] ) , 0 , 0 , 3.0f * dpiScale ) ;
} else {
dl - > AddRectFilled (
ImVec2 ( 0 , 0 ) ,
ImVec2 ( canvasW , canvasH ) ,
col
) ;
}
}
2023-02-25 18:04:17 -05:00
FurnaceGUITutorialDef : : FurnaceGUITutorialDef ( const char * n , std : : initializer_list < FurnaceGUITutorialStep > step ) :
name ( n ) {
steps = step ;
}
2024-04-01 00:35:59 -04:00
// CV
// 320x224
// renderer details:
// two 80x56 tile planes (40x28 is visible)
// 256 colors
// 4096 tiles (image is 256-color, 256x1024)
// each tile is 8x8
static const unsigned char cvPalette [ 1024 ] = {
0x00 , 0x00 , 0x00 , 0xff , 0xb3 , 0x00 , 0x00 , 0xff , 0x00 , 0xa7 , 0x00 , 0xff ,
0xe5 , 0x93 , 0x00 , 0xff , 0x00 , 0x00 , 0xa6 , 0xff , 0x77 , 0x00 , 0x97 , 0xff ,
0x12 , 0x81 , 0xb1 , 0xff , 0xbe , 0xbe , 0xbe , 0xff , 0x51 , 0x51 , 0x51 , 0xff ,
0xfc , 0x00 , 0x00 , 0xff , 0x00 , 0xff , 0x00 , 0xff , 0xff , 0xff , 0x1d , 0xff ,
0x00 , 0x00 , 0xfa , 0xff , 0xff , 0x00 , 0xff , 0xff , 0x1f , 0xfa , 0xff , 0xff ,
0xff , 0xff , 0xff , 0xff , 0x00 , 0x00 , 0x00 , 0xff , 0x00 , 0x01 , 0x67 , 0xff ,
0x04 , 0x00 , 0x89 , 0xff , 0x00 , 0x03 , 0xab , 0xff , 0x00 , 0x00 , 0xdc , 0xff ,
0x04 , 0x00 , 0xfe , 0xff , 0x00 , 0x63 , 0x00 , 0xff , 0x00 , 0x5f , 0x5f , 0xff ,
0x01 , 0x62 , 0x85 , 0xff , 0x05 , 0x5d , 0xb6 , 0xff , 0x00 , 0x61 , 0xd9 , 0xff ,
0x02 , 0x5f , 0xfb , 0xff , 0x00 , 0x8a , 0x06 , 0xff , 0x00 , 0x8a , 0x59 , 0xff ,
0x00 , 0x85 , 0x8a , 0xff , 0x06 , 0x87 , 0xb1 , 0xff , 0x00 , 0x8b , 0xd3 , 0xff ,
0x02 , 0x87 , 0xff , 0xff , 0x00 , 0xb0 , 0x00 , 0xff , 0x00 , 0xb1 , 0x62 , 0xff ,
0x00 , 0xaf , 0x84 , 0xff , 0x02 , 0xad , 0xa7 , 0xff , 0x00 , 0xaf , 0xd8 , 0xff ,
0x02 , 0xb1 , 0xfe , 0xff , 0x00 , 0xd8 , 0x05 , 0xff , 0x00 , 0xdb , 0x5c , 0xff ,
0x00 , 0xd7 , 0x8e , 0xff , 0x03 , 0xd5 , 0xb0 , 0xff , 0x00 , 0xd9 , 0xd2 , 0xff ,
0x00 , 0xd4 , 0xff , 0xff , 0x00 , 0xff , 0x00 , 0xff , 0x00 , 0xff , 0x66 , 0xff ,
0x00 , 0xff , 0x88 , 0xff , 0x03 , 0xff , 0xaa , 0xff , 0x00 , 0xff , 0xdb , 0xff ,
0x00 , 0xff , 0xfd , 0xff , 0x64 , 0x00 , 0x00 , 0xff , 0x64 , 0x00 , 0x65 , 0xff ,
0x5c , 0x03 , 0x87 , 0xff , 0x60 , 0x01 , 0xa9 , 0xff , 0x64 , 0x00 , 0xda , 0xff ,
0x5c , 0x00 , 0xfc , 0xff , 0x61 , 0x60 , 0x00 , 0xff , 0x5d , 0x5d , 0x5d , 0xff ,
0x65 , 0x5f , 0x83 , 0xff , 0x5d , 0x61 , 0xb5 , 0xff , 0x61 , 0x5f , 0xd7 , 0xff ,
0x59 , 0x63 , 0xf9 , 0xff , 0x61 , 0x88 , 0x04 , 0xff , 0x5e , 0x87 , 0x57 , 0xff ,
0x62 , 0x83 , 0x88 , 0xff , 0x5e , 0x8b , 0xaf , 0xff , 0x62 , 0x86 , 0xe0 , 0xff ,
0x5a , 0x8a , 0xff , 0xff , 0x5e , 0xae , 0x00 , 0xff , 0x5e , 0xaf , 0x60 , 0xff ,
0x62 , 0xad , 0x83 , 0xff , 0x5a , 0xae , 0xb4 , 0xff , 0x5e , 0xac , 0xd6 , 0xff ,
0x5a , 0xb5 , 0xfc , 0xff , 0x5e , 0xd5 , 0x03 , 0xff , 0x5e , 0xd9 , 0x5b , 0xff ,
0x62 , 0xd4 , 0x8c , 0xff , 0x5b , 0xd9 , 0xae , 0xff , 0x5f , 0xd7 , 0xd0 , 0xff ,
0x63 , 0xd2 , 0xff , 0xff , 0x5f , 0xff , 0x00 , 0xff , 0x5f , 0xff , 0x64 , 0xff ,
0x63 , 0xff , 0x86 , 0xff , 0x5b , 0xff , 0xa8 , 0xff , 0x5f , 0xfe , 0xd9 , 0xff ,
0x63 , 0xfc , 0xfc , 0xff , 0x88 , 0x01 , 0x00 , 0xff , 0x88 , 0x01 , 0x62 , 0xff ,
0x8c , 0x00 , 0x84 , 0xff , 0x84 , 0x01 , 0xb5 , 0xff , 0x88 , 0x00 , 0xd7 , 0xff ,
0x8c , 0x00 , 0xfa , 0xff , 0x85 , 0x60 , 0x07 , 0xff , 0x81 , 0x60 , 0x5a , 0xff ,
0x89 , 0x5f , 0x8f , 0xff , 0x8d , 0x5e , 0xb2 , 0xff , 0x85 , 0x62 , 0xd4 , 0xff ,
0x89 , 0x5d , 0xff , 0xff , 0x85 , 0x8b , 0x01 , 0xff , 0x82 , 0x87 , 0x63 , 0xff ,
0x86 , 0x86 , 0x86 , 0xff , 0x8a , 0x84 , 0xa8 , 0xff , 0x86 , 0x89 , 0xdd , 0xff ,
0x8a , 0x87 , 0xff , 0xff , 0x82 , 0xb1 , 0x00 , 0xff , 0x82 , 0xb2 , 0x5e , 0xff ,
0x86 , 0xb0 , 0x80 , 0xff , 0x8a , 0xab , 0xb1 , 0xff , 0x82 , 0xaf , 0xd3 , 0xff ,
0x8a , 0xaf , 0xff , 0xff , 0x82 , 0xd8 , 0x00 , 0xff , 0x82 , 0xdc , 0x58 , 0xff ,
0x86 , 0xd7 , 0x89 , 0xff , 0x8b , 0xd5 , 0xab , 0xff , 0x83 , 0xd7 , 0xdc , 0xff ,
0x87 , 0xd5 , 0xff , 0xff , 0x83 , 0xff , 0x00 , 0xff , 0x83 , 0xff , 0x61 , 0xff ,
0x87 , 0xff , 0x83 , 0xff , 0x8b , 0xfd , 0xb4 , 0xff , 0x83 , 0xff , 0xd7 , 0xff ,
0x87 , 0xff , 0xf9 , 0xff , 0xac , 0x01 , 0x07 , 0xff , 0xac , 0x04 , 0x5f , 0xff ,
0xb0 , 0x02 , 0x81 , 0xff , 0xb4 , 0x00 , 0xb2 , 0xff , 0xac , 0x02 , 0xd4 , 0xff ,
0xb0 , 0x00 , 0xff , 0xff , 0xb5 , 0x5d , 0x04 , 0xff , 0xb1 , 0x5d , 0x57 , 0xff ,
0xad , 0x62 , 0x8d , 0xff , 0xb1 , 0x60 , 0xaf , 0xff , 0xb5 , 0x5c , 0xe0 , 0xff ,
0xad , 0x60 , 0xff , 0xff , 0xb5 , 0x88 , 0x00 , 0xff , 0xb1 , 0x84 , 0x60 , 0xff ,
0xaa , 0x88 , 0x83 , 0xff , 0xae , 0x84 , 0xb4 , 0xff , 0xb6 , 0x86 , 0xda , 0xff ,
0xae , 0x8a , 0xfc , 0xff , 0xb2 , 0xab , 0x03 , 0xff , 0xb2 , 0xaf , 0x5b , 0xff ,
0xaa , 0xb0 , 0x8c , 0xff , 0xae , 0xae , 0xae , 0xff , 0xb2 , 0xac , 0xd0 , 0xff ,
0xaa , 0xae , 0xff , 0xff , 0xb2 , 0xd5 , 0x00 , 0xff , 0xb2 , 0xd6 , 0x64 , 0xff ,
0xaa , 0xda , 0x86 , 0xff , 0xae , 0xd8 , 0xa8 , 0xff , 0xb3 , 0xd4 , 0xd9 , 0xff ,
0xab , 0xd8 , 0xfc , 0xff , 0xb3 , 0xff , 0x00 , 0xff , 0xb3 , 0xff , 0x5e , 0xff ,
0xab , 0xff , 0x80 , 0xff , 0xaf , 0xff , 0xb1 , 0xff , 0xb3 , 0xfe , 0xd4 , 0xff ,
0xab , 0xff , 0xff , 0xff , 0xdc , 0x00 , 0x05 , 0xff , 0xdc , 0x01 , 0x5c , 0xff ,
0xd4 , 0x02 , 0x8d , 0xff , 0xd8 , 0x01 , 0xaf , 0xff , 0xdc , 0x00 , 0xd2 , 0xff ,
0xd4 , 0x00 , 0xff , 0xff , 0xd9 , 0x60 , 0x01 , 0xff , 0xd5 , 0x5d , 0x63 , 0xff ,
0xd9 , 0x5b , 0x86 , 0xff , 0xd5 , 0x63 , 0xac , 0xff , 0xd9 , 0x5f , 0xdd , 0xff ,
0xdd , 0x5d , 0xff , 0xff , 0xd5 , 0x86 , 0x00 , 0xff , 0xd5 , 0x87 , 0x5e , 0xff ,
0xd9 , 0x85 , 0x80 , 0xff , 0xd2 , 0x87 , 0xb1 , 0xff , 0xda , 0x89 , 0xd7 , 0xff ,
0xde , 0x84 , 0xff , 0xff , 0xd6 , 0xae , 0x00 , 0xff , 0xd6 , 0xb1 , 0x58 , 0xff ,
0xda , 0xad , 0x89 , 0xff , 0xd2 , 0xb1 , 0xab , 0xff , 0xd6 , 0xac , 0xdc , 0xff ,
0xda , 0xaa , 0xff , 0xff , 0xd6 , 0xd8 , 0x00 , 0xff , 0xd6 , 0xd9 , 0x61 , 0xff ,
0xda , 0xd7 , 0x83 , 0xff , 0xd2 , 0xd8 , 0xb4 , 0xff , 0xd7 , 0xd7 , 0xd7 , 0xff ,
0xdb , 0xd5 , 0xf9 , 0xff , 0xd7 , 0xff , 0x04 , 0xff , 0xd7 , 0xff , 0x5b , 0xff ,
0xdb , 0xfe , 0x8c , 0xff , 0xd3 , 0xff , 0xaf , 0xff , 0xd7 , 0xff , 0xd1 , 0xff ,
0xdb , 0xfc , 0xff , 0xff , 0xff , 0x00 , 0x02 , 0xff , 0xff , 0x01 , 0x68 , 0xff ,
0xff , 0x00 , 0x8a , 0xff , 0xfc , 0x04 , 0xac , 0xff , 0xff , 0x00 , 0xde , 0xff ,
0xff , 0x00 , 0xff , 0xff , 0xfd , 0x63 , 0x00 , 0xff , 0xf9 , 0x60 , 0x60 , 0xff ,
0xfd , 0x5e , 0x83 , 0xff , 0xff , 0x5d , 0xb8 , 0xff , 0xfd , 0x62 , 0xda , 0xff ,
0xff , 0x60 , 0xfc , 0xff , 0xf9 , 0x86 , 0x03 , 0xff , 0xf9 , 0x8a , 0x5b , 0xff ,
0xfd , 0x85 , 0x8c , 0xff , 0xff , 0x84 , 0xae , 0xff , 0xfa , 0x88 , 0xd0 , 0xff ,
0xff , 0x87 , 0xff , 0xff , 0xfa , 0xb1 , 0x00 , 0xff , 0xff , 0xab , 0x64 , 0xff ,
0xfe , 0xb0 , 0x86 , 0xff , 0xff , 0xae , 0xa8 , 0xff , 0xfa , 0xaf , 0xd9 , 0xff ,
0xfe , 0xad , 0xfc , 0xff , 0xfa , 0xdb , 0x00 , 0xff , 0xff , 0xd6 , 0x5e , 0xff ,
0xfe , 0xda , 0x80 , 0xff , 0xff , 0xd5 , 0xb1 , 0xff , 0xfb , 0xd9 , 0xd4 , 0xff ,
0xff , 0xd5 , 0xff , 0xff , 0xfb , 0xff , 0x01 , 0xff , 0xff , 0xf9 , 0x63 , 0xff ,
0xff , 0xff , 0x89 , 0xff , 0xff , 0xff , 0xac , 0xff , 0xfb , 0xff , 0xdd , 0xff ,
0xff , 0xff , 0xff , 0xff , 0x04 , 0x04 , 0x04 , 0xff , 0x0c , 0x0c , 0x0c , 0xff ,
0x18 , 0x18 , 0x18 , 0xff , 0x20 , 0x20 , 0x20 , 0xff , 0x2d , 0x2d , 0x2d , 0xff ,
0x35 , 0x35 , 0x35 , 0xff , 0x41 , 0x41 , 0x41 , 0xff , 0x49 , 0x49 , 0x49 , 0xff ,
0x55 , 0x55 , 0x55 , 0xff , 0x61 , 0x61 , 0x61 , 0xff , 0x69 , 0x69 , 0x69 , 0xff ,
0x71 , 0x71 , 0x71 , 0xff , 0x7d , 0x7d , 0x7d , 0xff , 0x8a , 0x8a , 0x8a , 0xff ,
0x92 , 0x92 , 0x92 , 0xff , 0x9a , 0x9a , 0x9a , 0xff , 0xa6 , 0xa6 , 0xa6 , 0xff ,
0xb2 , 0xb2 , 0xb2 , 0xff , 0xba , 0xba , 0xba , 0xff , 0xc2 , 0xc2 , 0xc2 , 0xff ,
0xce , 0xce , 0xce , 0xff , 0xdb , 0xdb , 0xdb , 0xff , 0xe3 , 0xe3 , 0xe3 , 0xff ,
0xeb , 0xeb , 0xeb , 0xff
} ;
# include "tileData.h"
# define SE_SHOT1 0, 0, 48
# define SE_EXPL1 1, 1, 67
# define SE_PICKUP1 2, 2, 67
# define SE_PICKUP2 3, 2, 69
# define SE_DEATH_C1 4, 0, 48
# define SE_DEATH_C2 5, 1, 48
# define SE_SHOT2 6, 0, 48
# define SE_TYPEWRITER 7, 0, 48
# define SE_TRANSITION1 8, 2, 43
# define SE_TRANSITION2 9, 2, 48
# define SE_INIT 10, 2, 48
# define SE_RESPAWN 11, 2, 48
# define SE_TANKMOVE 12, 3, 48
# define SE_VORTEXMOVE 13, 3, 55
# define SE_VORTEXSHOOT 14, 3, 48
# define SE_RESIST 15, 1, 48
template < typename T > T * FurnaceCV : : createObject ( short x , short y ) {
T * ret = new T ( this ) ;
ret - > x = x ;
ret - > y = y ;
sprite . push_back ( ret ) ;
return ret ;
}
void FurnaceCV : : soundEffect ( int ins , int chan , int note ) {
e - > noteOn ( chan + fxChanBase , ins + fxInsBase , note ) ;
/*
e - > dispatchCmd ( DivCommand ( DIV_CMD_INSTRUMENT , chan , ins , 1 ) ) ;
e - > dispatchCmd ( DivCommand ( DIV_CMD_NOTE_ON , chan , note ) ) ;
*/
}
void FurnaceCV : : stopSoundEffect ( int ins , int chan , int note ) {
e - > noteOff ( chan + fxChanBase ) ;
//e->dispatchCmd(DivCommand(DIV_CMD_NOTE_OFF,chan));
}
static const int floorBases [ 4 ] = {
0x40 , 0x48 , 0x60 , 0x68
} ;
void FurnaceCV : : buildStage ( int which ) {
if ( curStage ! = NULL ) {
delete [ ] curStage ;
curStage = NULL ;
}
curStage = new unsigned short [ 80 * 56 ] ;
stageWidth = 80 ;
stageHeight = 56 ;
int floorBase = floorBases [ rand ( ) & 3 ] ;
for ( int i = 0 ; i < stageHeight ; i + + ) {
for ( int j = 0 ; j < stageWidth ; j + + ) {
curStage [ i * stageWidth + j ] = floorBase + ( rand ( ) & 7 ) ;
}
}
// render
for ( int i = 0 ; i < stageHeight ; i + + ) {
for ( int j = 0 ; j < stageWidth ; j + + ) {
tile0 [ i ] [ j ] = curStage [ i * stageWidth + j ] ;
}
}
// prepare enemies
bool busy [ 28 ] [ 40 ] ;
memset ( busy , 0 , 28 * 40 * sizeof ( bool ) ) ;
// special stages
if ( ( which % 10 ) = = 9 ) {
// vortex
for ( int i = 0 ; i < 20 + ( which > > 2 ) ; i + + ) {
int tries = 0 ;
while ( tries < 20 ) {
int x = rand ( ) % 40 ;
int y = rand ( ) % 28 ;
int finalX = x < < 4 ;
int finalY = y < < 4 ;
if ( busy [ y ] [ x ] ) {
tries + + ;
continue ;
}
createObject < FurnaceCVEnemyVortex > ( finalX , finalY ) ;
createObject < FurnaceCVFurBallMedium > ( finalX - 4 , finalY - 4 ) ;
busy [ y ] [ x ] = true ;
break ;
}
}
} else if ( ( which % 10 ) = = 19 ) {
for ( int i = 0 ; i < 20 + ( which > > 2 ) ; i + + ) {
int tries = 0 ;
while ( tries < 20 ) {
int x = ( rand ( ) % 40 ) & ( ~ 1 ) ;
int y = ( rand ( ) % 28 ) & ( ~ 1 ) ;
int finalX = x < < 4 ;
int finalY = y < < 4 ;
if ( busy [ y ] [ x ] ) {
tries + + ;
continue ;
}
FurnaceCVEnemy1 * enemy = createObject < FurnaceCVEnemy1 > ( finalX , finalY ) ;
createObject < FurnaceCVFurBallLarge > ( finalX - 4 , finalY - 4 ) ;
enemy - > setType ( 3 ) ;
busy [ y ] [ x ] = true ;
busy [ y ] [ x + 1 ] = true ;
busy [ y + 1 ] [ x ] = true ;
busy [ y + 1 ] [ x + 1 ] = true ;
break ;
}
}
} else {
// large
if ( which > = 2 ) for ( int i = 0 ; i < ( rand ( ) % 3 ) + which - 2 ; i + + ) {
int tries = 0 ;
while ( tries < 20 ) {
int x = ( rand ( ) % 40 ) & ( ~ 1 ) ;
int y = ( rand ( ) % 28 ) & ( ~ 1 ) ;
int finalX = x < < 4 ;
int finalY = y < < 4 ;
if ( busy [ y ] [ x ] ) {
tries + + ;
continue ;
}
FurnaceCVEnemy1 * enemy = createObject < FurnaceCVEnemy1 > ( finalX , finalY ) ;
createObject < FurnaceCVFurBallLarge > ( finalX - 4 , finalY - 4 ) ;
enemy - > setType ( 2 ) ;
if ( which > 7 ) {
enemy - > setType ( ( rand ( ) % MAX ( 1 , 15 - which ) ) = = 0 ? 3 : 2 ) ;
}
busy [ y ] [ x ] = true ;
busy [ y ] [ x + 1 ] = true ;
busy [ y + 1 ] [ x ] = true ;
busy [ y + 1 ] [ x + 1 ] = true ;
break ;
}
}
// vortex
if ( which > = 4 ) for ( int i = 0 ; i < ( rand ( ) % ( 1 + which ) ) + ( which > > 1 ) ; i + + ) {
int tries = 0 ;
while ( tries < 20 ) {
int x = rand ( ) % 40 ;
int y = rand ( ) % 28 ;
int finalX = x < < 4 ;
int finalY = y < < 4 ;
if ( busy [ y ] [ x ] ) {
tries + + ;
continue ;
}
createObject < FurnaceCVEnemyVortex > ( finalX , finalY ) ;
createObject < FurnaceCVFurBallMedium > ( finalX - 4 , finalY - 4 ) ;
busy [ y ] [ x ] = true ;
break ;
}
}
// small
for ( int i = 0 ; i < 7 + ( rand ( ) % 4 ) + ( ( which & 3 ) < < 2 ) + ( which > > 1 ) ; i + + ) {
int tries = 0 ;
while ( tries < 20 ) {
int x = rand ( ) % 40 ;
int y = rand ( ) % 28 ;
int finalX = x < < 4 ;
int finalY = y < < 4 ;
if ( busy [ y ] [ x ] ) {
tries + + ;
continue ;
}
FurnaceCVEnemy1 * enemy = createObject < FurnaceCVEnemy1 > ( finalX , finalY ) ;
createObject < FurnaceCVFurBallMedium > ( finalX - 4 , finalY - 4 ) ;
if ( which > 0 ) {
enemy - > setType ( ( rand ( ) % MAX ( 1 , 8 - which ) ) = = 0 ? 1 : 0 ) ;
}
busy [ y ] [ x ] = true ;
break ;
}
}
// mines
for ( int i = 0 ; i < 7 + ( rand ( ) % 18 ) ; i + + ) {
int tries = 0 ;
while ( tries < 20 ) {
int x = rand ( ) % 40 ;
int y = rand ( ) % 28 ;
int finalX = x < < 4 ;
int finalY = y < < 4 ;
if ( busy [ y ] [ x ] ) {
tries + + ;
continue ;
}
createObject < FurnaceCVMine > ( finalX , finalY ) ;
busy [ y ] [ x ] = true ;
break ;
}
}
}
}
# define CV_FONTBASE_8x8 0x250
# define CV_FONTBASE_8x8_RED 0x2d0
# define CV_FONTBASE_8x16 0x0
void FurnaceCV : : putText ( int fontBase , bool fontHeight , String text , int x , int y ) {
int initX = x ;
for ( const char * i = text . c_str ( ) ; * i ; i + + ) {
if ( * i = = ' \n ' ) {
x = initX ;
y + = fontHeight ? 2 : 1 ;
continue ;
}
if ( y > = 28 ) break ;
tile1 [ y ] [ x ] = fontBase + ( ( * i ) & 15 ) + ( ( ( * i ) & ( ~ 15 ) ) < < ( fontHeight ? 2 : 1 ) ) ;
if ( fontHeight ) {
tile1 [ y + 1 ] [ x ] = fontBase + ( ( * i ) & 15 ) + 32 + ( ( ( * i ) & ( ~ 15 ) ) < < ( fontHeight ? 2 : 1 ) ) ;
}
x + + ;
if ( x > = 40 ) {
x = initX ;
y + = fontHeight ? 2 : 1 ;
}
}
}
void FurnaceCV : : startTyping ( const char * text , int x , int y ) {
typeAddr = text ;
typeX = x ;
typeY = y ;
typeXStart = x ;
typeYStart = y ;
typeDelay = 1 ;
soundEffect ( SE_TYPEWRITER ) ;
}
void FurnaceCV : : typeTick ( ) {
if ( typeAddr = = NULL ) return ;
unsigned char typeChar = ( unsigned char ) ( * typeAddr ) ;
if ( typeChar < 0x20 | | typeChar > = 0x80 ) {
switch ( typeChar ) {
case ' \n ' :
typeX = typeXStart ;
typeY + = 2 ;
if ( typeY > = typeYEnd ) typeY = typeYEnd ;
break ;
}
} else {
tile1 [ typeY ] [ typeX ] = ( typeChar & 15 ) | ( ( typeChar & ( ~ 15 ) ) < < 2 ) ;
tile1 [ typeY + 1 ] [ typeX ] = 32 | ( ( typeChar & 15 ) | ( ( typeChar & ( ~ 15 ) ) < < 2 ) ) ;
if ( + + typeX > typeXEnd ) {
typeX = typeXStart ;
typeY + = 2 ;
if ( typeY > = typeYEnd ) typeY = typeYEnd ;
}
}
if ( * ( + + typeAddr ) = = 0 ) {
typeAddr = NULL ;
stopSoundEffect ( SE_TYPEWRITER ) ;
}
}
void FurnaceCV : : rasterH ( int scanline ) {
}
void FurnaceCV : : render ( unsigned char joyIn ) {
// input
joyInputPrev = joyInput ;
joyInput = joyIn ;
joyInput | = (
( ImGui : : IsKeyDown ( ImGuiKey_X ) ? 1 : 0 ) |
( ImGui : : IsKeyDown ( ImGuiKey_Z ) ? 2 : 0 ) |
( ImGui : : IsKeyDown ( ImGuiKey_RightShift ) ? 4 : 0 ) |
( ImGui : : IsKeyDown ( ImGuiKey_Enter ) ? 8 : 0 ) |
( ImGui : : IsKeyDown ( ImGuiKey_UpArrow ) ? 16 : 0 ) |
( ImGui : : IsKeyDown ( ImGuiKey_DownArrow ) ? 32 : 0 ) |
( ImGui : : IsKeyDown ( ImGuiKey_LeftArrow ) ? 64 : 0 ) |
( ImGui : : IsKeyDown ( ImGuiKey_RightArrow ) ? 128 : 0 )
) ;
joyPressed = ( joyInputPrev ^ 0xff ) & joyInput ;
joyReleased = ( joyInput ^ 0xff ) & joyInputPrev ;
// logic
typeTick ( ) ;
int enemyCount = 0 ;
for ( size_t i = 0 ; i < sprite . size ( ) ; i + + ) {
for ( size_t j = i + 1 ; j < sprite . size ( ) ; j + + ) {
const short s_x0 = sprite [ i ] - > x + sprite [ i ] - > collX0 ;
const short s_x1 = sprite [ i ] - > x + sprite [ i ] - > collX1 ;
const short s_y0 = sprite [ i ] - > y + sprite [ i ] - > collY0 ;
const short s_y1 = sprite [ i ] - > y + sprite [ i ] - > collY1 ;
const short d_x0 = sprite [ j ] - > x + sprite [ j ] - > collX0 ;
const short d_x1 = sprite [ j ] - > x + sprite [ j ] - > collX1 ;
const short d_y0 = sprite [ j ] - > y + sprite [ j ] - > collY0 ;
const short d_y1 = sprite [ j ] - > y + sprite [ j ] - > collY1 ;
if ( d_y0 < s_y1 & & d_y1 > s_y0 & & d_x0 < s_x1 & & d_x1 > s_x0 ) {
sprite [ i ] - > collision ( sprite [ j ] ) ;
sprite [ j ] - > collision ( sprite [ i ] ) ;
}
}
sprite [ i ] - > tick ( ) ;
if ( sprite [ i ] - > dead ) {
delete sprite [ i ] ;
sprite . erase ( sprite . begin ( ) + i ) ;
i - - ;
}
}
if ( inGame ) {
if ( ticksToInit > 0 ) {
if ( - - ticksToInit < 1 ) {
e - > changeSongP ( 0 ) ;
e - > setOrder ( 0 ) ;
e - > play ( ) ;
buildStage ( stage ) ;
createObject < FurnaceCVPlayer > ( 160 , 112 ) ;
createObject < FurnaceCVFurBallLarge > ( 160 - 4 , 112 - 4 ) ;
soundEffect ( SE_INIT ) ;
}
} else {
bool hasEnemy = false ;
for ( FurnaceCVObject * i : sprite ) {
if ( i - > type = = CV_ENEMY ) {
hasEnemy = true ;
enemyCount + + ;
}
}
if ( ! hasEnemy ) {
inTransition = true ;
inGame = false ;
transWait = 100 ;
soundEffect ( SE_TRANSITION1 ) ;
stopSoundEffect ( 0 , 0 , 0 ) ;
stopSoundEffect ( 0 , 3 , 0 ) ;
respawnTime = 0 ;
for ( FurnaceCVObject * i : sprite ) {
i - > dead = true ;
}
memset ( tile0 , 0 , 80 * 56 * sizeof ( short ) ) ;
memset ( tile1 , 0 , 80 * 56 * sizeof ( short ) ) ;
}
}
if ( respawnTime > 0 ) {
if ( - - respawnTime < 1 ) {
if ( lives > 0 ) {
createObject < FurnaceCVPlayer > ( lastPlayerX , lastPlayerY ) ;
createObject < FurnaceCVFurBallLarge > ( lastPlayerX - 4 , lastPlayerY - 4 ) ;
soundEffect ( SE_RESPAWN ) ;
lives - - ;
} else {
if ( newHiScore ) {
inGame = false ;
inTransition = false ;
for ( FurnaceCVObject * i : sprite ) {
i - > dead = true ;
}
memset ( tile0 , 0 , 80 * 56 * sizeof ( short ) ) ;
memset ( tile1 , 0 , 80 * 56 * sizeof ( short ) ) ;
startTyping ( cvText [ 6 ] , 2 , 3 ) ;
e - > setConf ( " cvHiScore " , hiScore ) ;
e - > saveConf ( ) ;
curText = 6 ;
textWait = 90 ;
} else {
startTyping ( cvText [ 5 ] , 15 , 13 ) ;
}
}
}
}
// draw score
putText ( CV_FONTBASE_8x8_RED , false , " 1UP " , 0 , 0 ) ;
putText ( CV_FONTBASE_8x8 , false , fmt : : sprintf ( " %8d " , score ) , 3 , 0 ) ;
putText ( CV_FONTBASE_8x8_RED , false , " HI " , 15 , 0 ) ;
putText ( CV_FONTBASE_8x8 , false , fmt : : sprintf ( " %8d " , hiScore ) , 17 , 0 ) ;
tile1 [ 0 ] [ 31 ] = 0x27e ;
putText ( CV_FONTBASE_8x8 , false , fmt : : sprintf ( " *%2d " , enemyCount ) , 32 , 0 ) ;
tile1 [ 0 ] [ 36 ] = 0x27f ;
putText ( CV_FONTBASE_8x8 , false , fmt : : sprintf ( " *%2d " , lives ) , 37 , 0 ) ;
} else {
if ( inTransition ) {
if ( - - transWait < 0 ) {
stage + + ;
logV ( " stage %d " , stage + 1 ) ;
soundEffect ( SE_TRANSITION2 ) ;
buildStage ( stage ) ;
createObject < FurnaceCVPlayer > ( lastPlayerX , lastPlayerY ) ;
createObject < FurnaceCVFurBallLarge > ( lastPlayerX - 4 , lastPlayerY - 4 ) ;
inGame = true ;
}
if ( transWait = = 40 ) {
putText ( CV_FONTBASE_8x16 , true , fmt : : sprintf ( " STAGE %d " , stage + 2 ) , 16 , 13 ) ;
} else if ( transWait > 40 ) {
for ( int i = 1 ; i < 28 ; i + + ) {
for ( int j = 0 ; j < 40 ; j + + ) {
int result = 0x270 + ( j > > 3 ) + ( i > > 3 ) + ( transWait > > 1 ) - 32 ;
tile1 [ i ] [ j ] = ( result > = 0x270 & & result < = 0x27b ) ? result : 0 ;
}
}
} else if ( transWait = = 1 ) {
memset ( tile1 , 0 , 80 * 56 * sizeof ( short ) ) ;
}
} else {
if ( curText = = 1 ) {
if ( typeAddr = = NULL ) {
textWait = 1 ;
if ( joyPressed & 32 ) {
playSongs = false ;
}
if ( joyPressed ) {
pleaseInitSongs = true ;
textWait = 0 ;
}
}
} else if ( joyPressed & 15 & & curText < 5 ) {
textWait = 1 ;
typeAddr = NULL ;
}
if ( typeAddr = = NULL ) {
if ( - - textWait < 0 ) {
if ( curText = = 5 ) {
memset ( tile1 , 0 , 80 * 56 * sizeof ( short ) ) ;
inGame = true ;
} else {
memset ( tile1 , 0 , 80 * 56 * sizeof ( short ) ) ;
startTyping ( cvText [ curText + + ] , 2 , 3 ) ;
textWait = 90 ;
}
}
}
}
}
// render
if ( surface = = NULL ) return ;
SDL_LockSurface ( surface ) ;
// render here
unsigned int * p = ( unsigned int * ) surface - > pixels ;
unsigned int * pCopy = p ;
unsigned int * paletteInt = ( unsigned int * ) cvPalette ;
unsigned char * pb = prioBuf ;
unsigned short y0 = scrollY [ 0 ] ;
unsigned short y1 = scrollY [ 1 ] ;
for ( int i = 0 ; i < 224 ; i + + ) {
rasterH ( i ) ;
unsigned short x0 = scrollX [ 0 ] % 448 ;
unsigned short x1 = scrollX [ 1 ] % 448 ;
y0 % = 448 ;
y1 % = 448 ;
for ( int j = 0 ; j < 320 ; j + + ) {
unsigned short t0 = tile0 [ y0 > > 3 ] [ x0 > > 3 ] & 0xfff ;
unsigned short t1 = tile1 [ y1 > > 3 ] [ x1 > > 3 ] & 0xfff ;
unsigned char td0 = tileData [ ( ( t0 & 31 ) < < 3 ) | ( x0 & 7 ) | ( ( t0 & ( ~ 31 ) ) < < 6 ) | ( ( y0 & 7 ) < < 8 ) ] ;
unsigned char td1 = tileData [ ( ( t1 & 31 ) < < 3 ) | ( x1 & 7 ) | ( ( t1 & ( ~ 31 ) ) < < 6 ) | ( ( y1 & 7 ) < < 8 ) ] ;
if ( td1 ) {
* p + + = paletteInt [ td1 ] ;
* pb + + = 2 ;
} else if ( td0 ) {
* p + + = paletteInt [ td0 ] ;
* pb + + = 1 ;
} else {
* p + + = paletteInt [ bgColor ] ;
* pb + + = 0 ;
}
if ( + + x0 > = 640 ) x0 = 0 ;
if ( + + x1 > = 640 ) x1 = 0 ;
}
y0 + + ;
y1 + + ;
}
// draw sprites
p = pCopy ;
for ( FurnaceCVObject * i : sprite ) {
int jk = 0 ;
for ( int j = 0 ; j < i - > spriteHeight ; j + + ) {
for ( int k = 0 ; k < i - > spriteWidth ; k + + ) {
int dx = i - > x - viewX + ( k < < 3 ) ;
int dy = i - > y - viewY + ( j < < 3 ) ;
int ptr = dx + dy * 320 ;
int ptrC = ptr ;
unsigned short spriteTile = i - > spriteDef [ jk ] ;
for ( int l = 0 ; l < 8 ; l + + ) {
dx = i - > x - viewX + ( k < < 3 ) ;
if ( dy > = 0 & & dy < 224 ) for ( int m = 0 ; m < 8 ; m + + ) {
if ( dx > = 0 & & dx < 320 ) {
unsigned char data = tileData [ ( ( spriteTile & 31 ) < < 3 ) | m | ( ( spriteTile & ( ~ 31 ) ) < < 6 ) | ( l < < 8 ) ] ;
if ( data ) {
if ( i - > prio > = prioBuf [ ptr ] ) {
p [ ptr ] = paletteInt [ data ] ;
}
}
}
dx + + ;
ptr + + ;
}
dy + + ;
ptrC + = 320 ;
ptr = ptrC ;
}
jk + + ;
}
}
}
SDL_UnlockSurface ( surface ) ;
}
void FurnaceCV : : addScore ( int amount ) {
score + = amount ;
if ( score > = 99999999 ) score = 99999999 ;
if ( score > hiScore ) {
hiScore = score ;
newHiScore = true ;
}
}
void _tileDataRead ( void * user , struct GIF_WHDR * data ) {
( ( FurnaceCV * ) user ) - > tileDataRead ( data ) ;
}
void FurnaceCV : : tileDataRead ( struct GIF_WHDR * data ) {
logV ( " got tile: %d %d " , data - > xdim , data - > ydim ) ;
logV ( " frd: %d %d fro: %d %d " , data - > frxd , data - > fryd , data - > frxo , data - > fryo ) ;
memcpy ( tileData , data - > bptr , data - > xdim * data - > ydim ) ;
}
bool FurnaceCV : : init ( DivEngine * eng ) {
e = eng ;
tileData = new unsigned char [ 8 * 8 * 4096 ] ;
memset ( tileData , 0 , 8 * 8 * 4096 ) ;
GIF_Load ( ( void * ) tileDataC , tileDataC_len , _tileDataRead , NULL , this , 0 ) ;
surface = SDL_CreateRGBSurfaceWithFormat ( 0 , 320 , 224 , 32 , SDL_PIXELFORMAT_ARGB8888 ) ;
if ( surface = = NULL ) {
logE ( " FurnaceCV: couldn't create surface! " ) ;
return false ;
}
prioBuf = new unsigned char [ 320 * 224 ] ;
memset ( prioBuf , 0 , 320 * 224 ) ;
loadInstruments ( ) ;
return true ;
}
void FurnaceCV : : unload ( ) {
SDL_FreeSurface ( surface ) ;
delete [ ] tileData ;
delete [ ] prioBuf ;
if ( fxInsBase > = 0 ) {
for ( int i = e - > song . insLen - 1 ; i > = fxInsBase ; i - - ) {
e - > delInstrument ( i ) ;
}
}
if ( fxChanBase > = 0 ) {
e - > removeSystem ( e - > song . systemLen - 1 ) ;
}
if ( curStage ! = NULL ) {
delete [ ] curStage ;
curStage = NULL ;
}
}
# define IS_VISIBLE ((x-cv->viewX+(spriteWidth<<3))>=0 && (x-cv->viewX)<320 && (y-cv->viewY+(spriteHeight<<3))>=0 && (y-cv->viewY)<224)
# define IS_IN_AREA ((x+(spriteWidth<<3))>=0 && (x)<640 && (y+(spriteHeight<<3))>=0 && (y)<448)
# define HITS_BORDER (x<0 || y<0 || (x+(spriteWidth<<3))>=640 || (y+(spriteHeight<<3))>=448)
# define CONFINE_TO_BORDER \
if ( x < 0 ) x = 0 ; \
if ( y < 0 ) y = 0 ; \
if ( ( x + ( spriteWidth < < 3 ) ) > = 640 ) x = 639 - ( spriteWidth < < 3 ) ; \
if ( ( y + ( spriteHeight < < 3 ) ) > = 448 ) y = 447 - ( spriteHeight < < 3 ) ;
// FurnaceCVPlayer IMPLEMENTATION
void FurnaceCVPlayer : : collision ( FurnaceCVObject * other ) {
if ( other - > type = = CV_ENEMY_BULLET | |
other - > type = = CV_MINE | |
other - > type = = CV_ENEMY ) {
if ( ! invincible ) {
dead = true ;
cv - > respawnTime = 48 ;
2024-04-01 01:44:42 -04:00
cv - > shotType = 0 ;
2024-04-01 00:35:59 -04:00
cv - > soundEffect ( SE_DEATH_C1 ) ;
cv - > soundEffect ( SE_DEATH_C2 ) ;
cv - > createObject < FurnaceCVExplMedium > ( x - 8 , y ) ;
cv - > createObject < FurnaceCVExplMedium > ( x + 8 , y ) ;
cv - > createObject < FurnaceCVExplMedium > ( x , y - 8 ) ;
cv - > createObject < FurnaceCVExplMedium > ( x , y + 8 ) ;
cv - > createObject < FurnaceCVExplMedium > ( x , y ) ;
} else if ( other - > type = = CV_ENEMY | | other - > type = = CV_MINE ) {
cv - > soundEffect ( SE_EXPL1 ) ;
}
}
}
static const int shootDirOffsX [ 8 ] = {
16 , 16 , 8 , 0 , 0 , 0 , 8 , 16
} ;
static const int shootDirOffsY [ 8 ] = {
8 , 0 , 0 , 0 , 8 , 16 , 16 , 16
} ;
static const int shootDirOrient [ 8 ] = {
0x80 , 0 , 0 , 0 , 0x180 , 0x100 , 0x100 , 0x100
} ;
void FurnaceCVPlayer : : tick ( ) {
signed char sdX = 0 ;
signed char sdY = 0 ;
if ( cv - > joyInput & 16 ) {
speedY - = 12 ;
sdY = - 1 ;
if ( speedY < - 64 ) speedY = - 64 ;
} else if ( cv - > joyInput & 32 ) {
speedY + = 12 ;
sdY = 1 ;
if ( speedY > 64 ) speedY = 64 ;
} else {
if ( speedY > 0 ) {
speedY - = 12 ;
if ( speedY < 0 ) speedY = 0 ;
} else if ( speedY < 0 ) {
speedY + = 12 ;
if ( speedY > 0 ) speedY = 0 ;
}
}
if ( cv - > joyInput & 64 ) {
speedX - = 12 ;
sdX = - 1 ;
if ( speedX < - 64 ) speedX = - 64 ;
} else if ( cv - > joyInput & 128 ) {
speedX + = 12 ;
sdX = 1 ;
if ( speedX > 64 ) speedX = 64 ;
} else {
if ( speedX > 0 ) {
speedX - = 12 ;
if ( speedX < 0 ) speedX = 0 ;
} else if ( speedX < 0 ) {
speedX + = 12 ;
if ( speedX > 0 ) speedX = 0 ;
}
}
// sqrt(2)
if ( speedX & & speedY ) {
if ( speedX > 45 ) speedX = 45 ;
if ( speedX < - 45 ) speedX = - 45 ;
if ( speedY > 45 ) speedY = 45 ;
if ( speedY < - 45 ) speedY = - 45 ;
}
subX + = speedX ;
while ( subX > = 32 ) {
x + + ;
subX - = 32 ;
}
while ( subX < 0 ) {
x - - ;
subX + = 32 ;
}
subY + = speedY ;
while ( subY > = 32 ) {
y + + ;
subY - = 32 ;
}
while ( subY < 0 ) {
y - - ;
subY + = 32 ;
}
if ( HITS_BORDER ) {
CONFINE_TO_BORDER ;
}
cv - > lastPlayerX = x ;
cv - > lastPlayerY = y ;
if ( sdX > 0 & & sdY > 0 ) shootDir = 7 ;
if ( sdX > 0 & & sdY < 0 ) shootDir = 1 ;
if ( sdX < 0 & & sdY > 0 ) shootDir = 5 ;
if ( sdX < 0 & & sdY < 0 ) shootDir = 3 ;
if ( sdX < 0 & & sdY = = 0 ) shootDir = 4 ;
if ( sdX > 0 & & sdY = = 0 ) shootDir = 0 ;
if ( sdX = = 0 & & sdY < 0 ) shootDir = 2 ;
if ( sdX = = 0 & & sdY > 0 ) shootDir = 6 ;
if ( cv - > joyPressed & 1 ) {
shotTimer = ( cv - > shotType = = 2 ) ? 5 : 9 ;
if ( cv - > shotType = = 1 ) {
cv - > soundEffect ( SE_SHOT2 ) ;
} else {
cv - > soundEffect ( SE_SHOT1 ) ;
}
FurnaceCVBullet * b = cv - > createObject < FurnaceCVBullet > ( x + shootDirOffsX [ shootDir ] , y + shootDirOffsY [ shootDir ] ) ;
b - > orient = shootDir ;
b - > setType ( ( cv - > shotType = = 1 ) ? 1 : 0 ) ;
switch ( shootDir ) {
case 0 :
case 1 :
case 7 :
b - > speedX = 160 ;
break ;
case 3 :
case 4 :
case 5 :
b - > speedX = - 160 ;
break ;
default :
b - > speedX = 0 ;
break ;
}
switch ( shootDir ) {
case 1 :
case 2 :
case 3 :
b - > speedY = - 160 ;
break ;
case 5 :
case 6 :
case 7 :
b - > speedY = 160 ;
break ;
default :
b - > speedY = 0 ;
break ;
}
}
if ( cv - > joyInput & 1 ) {
if ( - - shotTimer < 1 ) {
shotTimer = ( cv - > shotType = = 2 ) ? 4 : 8 ;
if ( cv - > shotType = = 1 ) {
cv - > soundEffect ( SE_SHOT2 ) ;
} else {
cv - > soundEffect ( SE_SHOT1 ) ;
}
FurnaceCVBullet * b = cv - > createObject < FurnaceCVBullet > ( x + shootDirOffsX [ shootDir ] , y + shootDirOffsY [ shootDir ] ) ;
b - > orient = shootDir ;
b - > setType ( ( cv - > shotType = = 1 ) ? 1 : 0 ) ;
switch ( shootDir ) {
case 0 :
case 1 :
case 7 :
b - > speedX = 160 ;
break ;
case 3 :
case 4 :
case 5 :
b - > speedX = - 160 ;
break ;
default :
b - > speedX = 0 ;
break ;
}
switch ( shootDir ) {
case 1 :
case 2 :
case 3 :
b - > speedY = - 160 ;
break ;
case 5 :
case 6 :
case 7 :
b - > speedY = 160 ;
break ;
default :
b - > speedY = 0 ;
break ;
}
if ( cv - > shotType = = 2 ) {
b - > speedX + = ( rand ( ) % 64 ) - 32 ;
b - > speedY + = ( rand ( ) % 64 ) - 32 ;
}
}
}
if ( invincible > 0 ) {
invincible - - ;
}
if ( invincible & 1 ) {
memset ( spriteDef , 0 , 9 * sizeof ( unsigned short ) ) ;
} else {
spriteDef [ 0 ] = 0x10 + ( ( animFrame > > 6 ) < < 2 ) + shootDirOrient [ shootDir ] ;
spriteDef [ 1 ] = 0x11 + ( ( animFrame > > 6 ) < < 2 ) + shootDirOrient [ shootDir ] ;
spriteDef [ 2 ] = 0x12 + ( ( animFrame > > 6 ) < < 2 ) + shootDirOrient [ shootDir ] ;
spriteDef [ 3 ] = 0x30 + ( ( animFrame > > 6 ) < < 2 ) + shootDirOrient [ shootDir ] ;
spriteDef [ 4 ] = 0x31 + ( ( animFrame > > 6 ) < < 2 ) + shootDirOrient [ shootDir ] ;
spriteDef [ 5 ] = 0x32 + ( ( animFrame > > 6 ) < < 2 ) + shootDirOrient [ shootDir ] ;
spriteDef [ 6 ] = 0x50 + ( ( animFrame > > 6 ) < < 2 ) + shootDirOrient [ shootDir ] ;
spriteDef [ 7 ] = 0x51 + ( ( animFrame > > 6 ) < < 2 ) + shootDirOrient [ shootDir ] ;
spriteDef [ 8 ] = 0x52 + ( ( animFrame > > 6 ) < < 2 ) + shootDirOrient [ shootDir ] ;
}
animFrame + = MAX ( fabs ( speedX ) , fabs ( speedY ) ) ;
// camera
cv - > viewX = x - 160 + 12 ;
cv - > viewY = y - 112 + 12 ;
if ( cv - > viewX < 0 ) cv - > viewX = 0 ;
if ( cv - > viewX > 320 ) cv - > viewX = 320 ;
if ( cv - > viewY < 0 ) cv - > viewY = 0 ;
if ( cv - > viewY > 224 ) cv - > viewY = 224 ;
cv - > scrollX [ 0 ] = cv - > viewX ;
cv - > scrollY [ 0 ] = cv - > viewY ;
}
// FurnaceCVBullet IMPLEMENTATION
void FurnaceCVBullet : : setType ( unsigned char t ) {
bulletType = t ;
if ( bulletType = = 1 ) {
spriteWidth = 2 ;
spriteHeight = 2 ;
switch ( orient ) {
case 0 :
spriteDef [ 0 ] = 0x496 ;
spriteDef [ 1 ] = 0x497 ;
spriteDef [ 2 ] = 0x4b6 ;
spriteDef [ 3 ] = 0x4b7 ;
break ;
case 1 :
spriteDef [ 0 ] = 0x49c ;
spriteDef [ 1 ] = 0x49d ;
spriteDef [ 2 ] = 0x4bc ;
spriteDef [ 3 ] = 0x4bd ;
break ;
case 2 :
spriteDef [ 0 ] = 0x494 ;
spriteDef [ 1 ] = 0x495 ;
spriteDef [ 2 ] = 0x4b4 ;
spriteDef [ 3 ] = 0x4b5 ;
break ;
case 3 :
spriteDef [ 0 ] = 0x45e ;
spriteDef [ 1 ] = 0x45f ;
spriteDef [ 2 ] = 0x47e ;
spriteDef [ 3 ] = 0x47f ;
break ;
case 4 :
spriteDef [ 0 ] = 0x49a ;
spriteDef [ 1 ] = 0x49b ;
spriteDef [ 2 ] = 0x4ba ;
spriteDef [ 3 ] = 0x4bb ;
break ;
case 5 :
spriteDef [ 0 ] = 0x45c ;
spriteDef [ 1 ] = 0x45d ;
spriteDef [ 2 ] = 0x47c ;
spriteDef [ 3 ] = 0x47d ;
break ;
case 6 :
spriteDef [ 0 ] = 0x498 ;
spriteDef [ 1 ] = 0x499 ;
spriteDef [ 2 ] = 0x4b8 ;
spriteDef [ 3 ] = 0x4b9 ;
break ;
case 7 :
spriteDef [ 0 ] = 0x49e ;
spriteDef [ 1 ] = 0x49f ;
spriteDef [ 2 ] = 0x4be ;
spriteDef [ 3 ] = 0x4bf ;
break ;
}
collX0 = 0 ;
collX1 = 15 ;
collY0 = 0 ;
collY1 = 15 ;
life = 11 ;
}
}
void FurnaceCVBullet : : killBullet ( ) {
if ( bulletType = = 1 ) {
cv - > soundEffect ( SE_EXPL1 ) ;
FurnaceCVBullet * b1 = cv - > createObject < FurnaceCVBullet > ( x + 4 , y + 4 ) ;
FurnaceCVBullet * b2 = cv - > createObject < FurnaceCVBullet > ( x + 4 , y + 4 ) ;
FurnaceCVBullet * b3 = cv - > createObject < FurnaceCVBullet > ( x + 4 , y + 4 ) ;
switch ( orient ) {
case 0 :
b1 - > speedX = 240 ;
b1 - > speedY = - 100 ;
b2 - > speedX = 240 ;
b2 - > speedY = 0 ;
b3 - > speedX = 240 ;
b3 - > speedY = 100 ;
break ;
case 1 :
b1 - > speedX = 130 ;
b1 - > speedY = - 170 ;
b2 - > speedX = 170 ;
b2 - > speedY = - 170 ;
b3 - > speedX = 170 ;
b3 - > speedY = - 130 ;
break ;
case 2 :
b1 - > speedX = - 100 ;
b1 - > speedY = - 240 ;
b2 - > speedX = 0 ;
b2 - > speedY = - 240 ;
b3 - > speedX = 100 ;
b3 - > speedY = - 240 ;
break ;
case 3 :
b1 - > speedX = - 130 ;
b1 - > speedY = - 170 ;
b2 - > speedX = - 170 ;
b2 - > speedY = - 170 ;
b3 - > speedX = - 170 ;
b3 - > speedY = - 130 ;
break ;
case 4 :
b1 - > speedX = - 240 ;
b1 - > speedY = - 100 ;
b2 - > speedX = - 240 ;
b2 - > speedY = 0 ;
b3 - > speedX = - 240 ;
b3 - > speedY = 100 ;
break ;
case 5 :
b1 - > speedX = - 130 ;
b1 - > speedY = 170 ;
b2 - > speedX = - 170 ;
b2 - > speedY = 170 ;
b3 - > speedX = - 170 ;
b3 - > speedY = 130 ;
break ;
case 6 :
b1 - > speedX = - 100 ;
b1 - > speedY = 240 ;
b2 - > speedX = 0 ;
b2 - > speedY = 240 ;
b3 - > speedX = 100 ;
b3 - > speedY = 240 ;
break ;
case 7 :
b1 - > speedX = 130 ;
b1 - > speedY = 170 ;
b2 - > speedX = 170 ;
b2 - > speedY = 170 ;
b3 - > speedX = 170 ;
b3 - > speedY = 130 ;
break ;
}
b1 - > orient = orient ;
b2 - > orient = orient ;
b3 - > orient = orient ;
cv - > createObject < FurnaceCVExplMedium > ( x - 8 , y - 8 ) ;
} else {
cv - > createObject < FurnaceCVExplTiny > ( x , y ) ;
}
}
void FurnaceCVBullet : : collision ( FurnaceCVObject * other ) {
if ( other - > type = = CV_ENEMY | | other - > type = = CV_MINE ) {
dead = true ;
killBullet ( ) ;
}
}
void FurnaceCVBullet : : tick ( ) {
subX + = speedX ;
while ( subX > = 32 ) {
x + + ;
subX - = 32 ;
}
while ( subX < 0 ) {
x - - ;
subX + = 32 ;
}
subY + = speedY ;
while ( subY > = 32 ) {
y + + ;
subY - = 32 ;
}
while ( subY < 0 ) {
y - - ;
subY + = 32 ;
}
if ( life > 0 ) {
if ( - - life < = 0 ) {
dead = true ;
killBullet ( ) ;
}
}
if ( ! IS_IN_AREA ) {
dead = true ;
}
}
// FurnaceCVEnemyBullet IMPLEMENTATION
void FurnaceCVEnemyBullet : : setType ( unsigned char type ) {
bulletType = type ;
}
void FurnaceCVEnemyBullet : : tick ( ) {
subX + = speedX ;
while ( subX > = 32 ) {
x + + ;
subX - = 32 ;
}
while ( subX < 0 ) {
x - - ;
subX + = 32 ;
}
subY + = speedY ;
while ( subY > = 32 ) {
y + + ;
subY - = 32 ;
}
while ( subY < 0 ) {
y - - ;
subY + = 32 ;
}
if ( bulletType = = 1 ) {
animFrame + = 10 + ( rand ( ) % 12 ) ;
spriteDef [ 0 ] = 0x28 + ( animFrame > > 6 ) ;
}
if ( ! IS_IN_AREA ) {
dead = true ;
}
}
// FurnaceCVEnemy1 IMPLEMENTATION
void FurnaceCVEnemy1 : : collision ( FurnaceCVObject * other ) {
if ( other - > type = = CV_BULLET | | other - > type = = CV_PLAYER ) {
if ( - - health < = 0 ) {
dead = true ;
if ( ( rand ( ) % 7 ) = = 0 ) {
switch ( rand ( ) % 10 ) {
case 0 :
cv - > createObject < FurnaceCVExtraLife > ( x + ( enemyType > = 2 ? 8 : 0 ) , y + ( enemyType > = 2 ? 8 : 0 ) ) ;
break ;
case 1 : case 2 : case 3 : case 4 :
cv - > createObject < FurnaceCVPowerupP > ( x + ( enemyType > = 2 ? 8 : 0 ) , y + ( enemyType > = 2 ? 8 : 0 ) ) ;
break ;
case 5 : case 6 : case 7 : case 8 : case 9 :
cv - > createObject < FurnaceCVPowerupS > ( x + ( enemyType > = 2 ? 8 : 0 ) , y + ( enemyType > = 2 ? 8 : 0 ) ) ;
break ;
}
}
cv - > soundEffect ( SE_EXPL1 ) ;
switch ( enemyType ) {
case 0 :
cv - > createObject < FurnaceCVExplMedium > ( x - 4 , y - 4 ) ;
cv - > addScore ( 100 ) ;
break ;
case 1 :
cv - > createObject < FurnaceCVExplMedium > ( x - 4 , y - 4 ) ;
cv - > addScore ( 200 ) ;
break ;
case 2 :
cv - > createObject < FurnaceCVExplMedium > ( x - 8 , y ) ;
cv - > createObject < FurnaceCVExplMedium > ( x + 8 , y ) ;
cv - > createObject < FurnaceCVExplMedium > ( x , y - 8 ) ;
cv - > createObject < FurnaceCVExplMedium > ( x , y + 8 ) ;
cv - > createObject < FurnaceCVExplMedium > ( x , y ) ;
cv - > addScore ( 400 ) ;
break ;
case 3 :
cv - > createObject < FurnaceCVExplMedium > ( x - 8 , y ) ;
cv - > createObject < FurnaceCVExplMedium > ( x + 8 , y ) ;
cv - > createObject < FurnaceCVExplMedium > ( x , y - 8 ) ;
cv - > createObject < FurnaceCVExplMedium > ( x , y + 8 ) ;
cv - > createObject < FurnaceCVExplMedium > ( x , y ) ;
cv - > addScore ( 800 ) ;
break ;
}
} else {
cv - > soundEffect ( SE_RESIST ) ;
}
} else if ( other - > type = = CV_ENEMY | | other - > type = = CV_MINE ) {
// reorient
orient = ( orient + 2 ) & 3 ;
}
}
void FurnaceCVEnemy1 : : tick ( ) {
if ( ! stopped ) {
switch ( orient ) {
case 0 :
x + = MAX ( 1 , enemyType ) ;
break ;
case 1 :
y - = MAX ( 1 , enemyType ) ;
break ;
case 2 :
x - = MAX ( 1 , enemyType ) ;
break ;
case 3 :
y + = MAX ( 1 , enemyType ) ;
break ;
}
animFrame + = 0x15 ;
}
if ( - - nextTime = = 0 ) {
nextTime = 64 + ( rand ( ) % 600 ) ;
stopped = ( ( rand ( ) % 10 ) = = 0 ) ;
if ( stopped ) {
nextTime > > = 2 ;
cv - > stopSoundEffect ( SE_TANKMOVE ) ;
} else {
unsigned char oldOrient = orient ;
orient = rand ( ) & 3 ;
if ( orient = = oldOrient ) orient = ( orient + 1 ) & 3 ;
cv - > soundEffect ( SE_TANKMOVE ) ;
}
}
if ( shootCooldown > 64 ) {
shootCooldown + = 16 * ( enemyType + 1 ) ;
} else if ( - - shootTime = = 0 ) {
shootTime = ( enemyType > = 2 ) ? 4 : 8 ;
for ( FurnaceCVObject * i : cv - > sprite ) {
if ( i - > type = = CV_PLAYER ) {
float dist = sqrt ( pow ( ( y + 8 ) - ( i - > y + 12 ) , 2.0 ) + pow ( ( i - > x + 12 ) - ( x + 8 ) , 2.0 ) ) ;
float angle = atan2 ( ( y + 8 ) - ( i - > y + 12 ) , ( i - > x + 12 ) - ( x + 8 ) ) / ( M_PI * 0.5 ) ;
if ( angle < 0.0 ) angle + = 4.0 ;
float angleDelta = angle - ( float ) orient ;
if ( angleDelta > = 2.0 ) angleDelta - = 4.0 ;
if ( angleDelta < - 2.0 ) angleDelta + = 4.0 ;
if ( fabs ( angleDelta ) < 0.3 & & dist < 256.0 & & IS_VISIBLE ) {
cv - > soundEffect ( SE_SHOT1 ) ;
shootCooldown + = 16 - enemyType * 2 ;
FurnaceCVEnemyBullet * b = cv - > createObject < FurnaceCVEnemyBullet > ( x + ( enemyType > = 2 ? 8 : 4 ) , y + ( enemyType > = 2 ? 8 : 4 ) ) ;
switch ( orient ) {
case 0 :
b - > speedX = 160 ;
break ;
case 1 :
b - > speedY = - 160 ;
break ;
case 2 :
b - > speedX = - 160 ;
break ;
case 3 :
b - > speedY = 160 ;
break ;
}
if ( enemyType > 0 ) {
b - > speedX + = ( rand ( ) % 64 ) - 32 ;
b - > speedY + = ( rand ( ) % 64 ) - 32 ;
}
}
break ;
}
}
}
if ( HITS_BORDER ) {
if ( x < 0 ) orient = 0 ;
if ( x > = 640 - 16 ) orient = 2 ;
if ( y < 0 ) orient = 3 ;
if ( y > = 224 - 16 ) orient = 1 ;
cv - > soundEffect ( SE_TANKMOVE ) ;
CONFINE_TO_BORDER ;
}
if ( enemyType > = 2 ) {
spriteWidth = 3 ;
spriteHeight = 3 ;
collX1 = 23 ;
collY1 = 23 ;
switch ( orient ) {
case 0 :
spriteDef [ 0 ] = 0x300 + ( ( animFrame > > 7 ) < < 2 ) + ( enemyType = = 3 ? 8 : 0 ) ;
spriteDef [ 1 ] = 0x301 + ( ( animFrame > > 7 ) < < 2 ) + ( enemyType = = 3 ? 8 : 0 ) ;
spriteDef [ 2 ] = 0x302 + ( ( animFrame > > 7 ) < < 2 ) + ( enemyType = = 3 ? 8 : 0 ) ;
spriteDef [ 3 ] = 0x320 + ( ( animFrame > > 7 ) < < 2 ) + ( enemyType = = 3 ? 8 : 0 ) ;
spriteDef [ 4 ] = 0x321 + ( ( animFrame > > 7 ) < < 2 ) + ( enemyType = = 3 ? 8 : 0 ) ;
spriteDef [ 5 ] = 0x322 + ( ( animFrame > > 7 ) < < 2 ) + ( enemyType = = 3 ? 8 : 0 ) ;
spriteDef [ 6 ] = 0x340 + ( ( animFrame > > 7 ) < < 2 ) + ( enemyType = = 3 ? 8 : 0 ) ;
spriteDef [ 7 ] = 0x341 + ( ( animFrame > > 7 ) < < 2 ) + ( enemyType = = 3 ? 8 : 0 ) ;
spriteDef [ 8 ] = 0x342 + ( ( animFrame > > 7 ) < < 2 ) + ( enemyType = = 3 ? 8 : 0 ) ;
break ;
case 1 :
spriteDef [ 0 ] = 0x280 + ( ( animFrame > > 7 ) < < 2 ) + ( enemyType = = 3 ? 8 : 0 ) ;
spriteDef [ 1 ] = 0x281 + ( ( animFrame > > 7 ) < < 2 ) + ( enemyType = = 3 ? 8 : 0 ) ;
spriteDef [ 2 ] = 0x282 + ( ( animFrame > > 7 ) < < 2 ) + ( enemyType = = 3 ? 8 : 0 ) ;
spriteDef [ 3 ] = 0x2a0 + ( ( animFrame > > 7 ) < < 2 ) + ( enemyType = = 3 ? 8 : 0 ) ;
spriteDef [ 4 ] = 0x2a1 + ( ( animFrame > > 7 ) < < 2 ) + ( enemyType = = 3 ? 8 : 0 ) ;
spriteDef [ 5 ] = 0x2a2 + ( ( animFrame > > 7 ) < < 2 ) + ( enemyType = = 3 ? 8 : 0 ) ;
spriteDef [ 6 ] = 0x2c0 + ( ( animFrame > > 7 ) < < 2 ) + ( enemyType = = 3 ? 8 : 0 ) ;
spriteDef [ 7 ] = 0x2c1 + ( ( animFrame > > 7 ) < < 2 ) + ( enemyType = = 3 ? 8 : 0 ) ;
spriteDef [ 8 ] = 0x2c2 + ( ( animFrame > > 7 ) < < 2 ) + ( enemyType = = 3 ? 8 : 0 ) ;
break ;
case 2 :
spriteDef [ 0 ] = 0x400 + ( ( animFrame > > 7 ) < < 2 ) + ( enemyType = = 3 ? 8 : 0 ) ;
spriteDef [ 1 ] = 0x401 + ( ( animFrame > > 7 ) < < 2 ) + ( enemyType = = 3 ? 8 : 0 ) ;
spriteDef [ 2 ] = 0x402 + ( ( animFrame > > 7 ) < < 2 ) + ( enemyType = = 3 ? 8 : 0 ) ;
spriteDef [ 3 ] = 0x420 + ( ( animFrame > > 7 ) < < 2 ) + ( enemyType = = 3 ? 8 : 0 ) ;
spriteDef [ 4 ] = 0x421 + ( ( animFrame > > 7 ) < < 2 ) + ( enemyType = = 3 ? 8 : 0 ) ;
spriteDef [ 5 ] = 0x422 + ( ( animFrame > > 7 ) < < 2 ) + ( enemyType = = 3 ? 8 : 0 ) ;
spriteDef [ 6 ] = 0x440 + ( ( animFrame > > 7 ) < < 2 ) + ( enemyType = = 3 ? 8 : 0 ) ;
spriteDef [ 7 ] = 0x441 + ( ( animFrame > > 7 ) < < 2 ) + ( enemyType = = 3 ? 8 : 0 ) ;
spriteDef [ 8 ] = 0x442 + ( ( animFrame > > 7 ) < < 2 ) + ( enemyType = = 3 ? 8 : 0 ) ;
break ;
case 3 :
spriteDef [ 0 ] = 0x380 + ( ( animFrame > > 7 ) < < 2 ) + ( enemyType = = 3 ? 8 : 0 ) ;
spriteDef [ 1 ] = 0x381 + ( ( animFrame > > 7 ) < < 2 ) + ( enemyType = = 3 ? 8 : 0 ) ;
spriteDef [ 2 ] = 0x382 + ( ( animFrame > > 7 ) < < 2 ) + ( enemyType = = 3 ? 8 : 0 ) ;
spriteDef [ 3 ] = 0x3a0 + ( ( animFrame > > 7 ) < < 2 ) + ( enemyType = = 3 ? 8 : 0 ) ;
spriteDef [ 4 ] = 0x3a1 + ( ( animFrame > > 7 ) < < 2 ) + ( enemyType = = 3 ? 8 : 0 ) ;
spriteDef [ 5 ] = 0x3a2 + ( ( animFrame > > 7 ) < < 2 ) + ( enemyType = = 3 ? 8 : 0 ) ;
spriteDef [ 6 ] = 0x3c0 + ( ( animFrame > > 7 ) < < 2 ) + ( enemyType = = 3 ? 8 : 0 ) ;
spriteDef [ 7 ] = 0x3c1 + ( ( animFrame > > 7 ) < < 2 ) + ( enemyType = = 3 ? 8 : 0 ) ;
spriteDef [ 8 ] = 0x3c2 + ( ( animFrame > > 7 ) < < 2 ) + ( enemyType = = 3 ? 8 : 0 ) ;
break ;
}
} else {
spriteWidth = 2 ;
spriteHeight = 2 ;
collX1 = 15 ;
collY1 = 15 ;
switch ( orient ) {
case 0 :
spriteDef [ 0 ] = 0x204 + ( ( animFrame > > 7 ) < < 1 ) + ( enemyType = = 1 ? 0x40 : 0 ) ;
spriteDef [ 1 ] = 0x205 + ( ( animFrame > > 7 ) < < 1 ) + ( enemyType = = 1 ? 0x40 : 0 ) ;
spriteDef [ 2 ] = 0x224 + ( ( animFrame > > 7 ) < < 1 ) + ( enemyType = = 1 ? 0x40 : 0 ) ;
spriteDef [ 3 ] = 0x225 + ( ( animFrame > > 7 ) < < 1 ) + ( enemyType = = 1 ? 0x40 : 0 ) ;
break ;
case 1 :
spriteDef [ 0 ] = 0x200 + ( ( animFrame > > 7 ) < < 1 ) + ( enemyType = = 1 ? 0x40 : 0 ) ;
spriteDef [ 1 ] = 0x201 + ( ( animFrame > > 7 ) < < 1 ) + ( enemyType = = 1 ? 0x40 : 0 ) ;
spriteDef [ 2 ] = 0x220 + ( ( animFrame > > 7 ) < < 1 ) + ( enemyType = = 1 ? 0x40 : 0 ) ;
spriteDef [ 3 ] = 0x221 + ( ( animFrame > > 7 ) < < 1 ) + ( enemyType = = 1 ? 0x40 : 0 ) ;
break ;
case 2 :
spriteDef [ 0 ] = 0x20c + ( ( animFrame > > 7 ) < < 1 ) + ( enemyType = = 1 ? 0x40 : 0 ) ;
spriteDef [ 1 ] = 0x20d + ( ( animFrame > > 7 ) < < 1 ) + ( enemyType = = 1 ? 0x40 : 0 ) ;
spriteDef [ 2 ] = 0x22c + ( ( animFrame > > 7 ) < < 1 ) + ( enemyType = = 1 ? 0x40 : 0 ) ;
spriteDef [ 3 ] = 0x22d + ( ( animFrame > > 7 ) < < 1 ) + ( enemyType = = 1 ? 0x40 : 0 ) ;
break ;
case 3 :
spriteDef [ 0 ] = 0x208 + ( ( animFrame > > 7 ) < < 1 ) + ( enemyType = = 1 ? 0x40 : 0 ) ;
spriteDef [ 1 ] = 0x209 + ( ( animFrame > > 7 ) < < 1 ) + ( enemyType = = 1 ? 0x40 : 0 ) ;
spriteDef [ 2 ] = 0x228 + ( ( animFrame > > 7 ) < < 1 ) + ( enemyType = = 1 ? 0x40 : 0 ) ;
spriteDef [ 3 ] = 0x229 + ( ( animFrame > > 7 ) < < 1 ) + ( enemyType = = 1 ? 0x40 : 0 ) ;
break ;
}
}
}
void FurnaceCVEnemy1 : : setType ( unsigned char t ) {
enemyType = t ;
switch ( enemyType ) {
case 0 :
health = 1 ;
break ;
case 1 :
health = 2 ;
break ;
case 2 :
health = 8 ;
break ;
case 3 :
health = 14 ;
break ;
}
}
// FurnaceCVExplTiny IMPLEMENTATION
void FurnaceCVExplTiny : : tick ( ) {
spriteDef [ 0 ] = 8 + ( animFrame > > 1 ) ;
if ( animFrame > = 4 ) {
spriteDef [ 0 ] = 0 ;
dead = true ;
}
animFrame + + ;
}
// FurnaceCVExplMedium IMPLEMENTATION
void FurnaceCVExplMedium : : tick ( ) {
if ( ( animFrame / 3 ) > = 5 ) {
memset ( spriteDef , 0 , 9 * sizeof ( unsigned short ) ) ;
dead = true ;
} else {
spriteDef [ 0 ] = 0x210 + ( animFrame / 3 ) * 3 ;
spriteDef [ 1 ] = 0x211 + ( animFrame / 3 ) * 3 ;
spriteDef [ 2 ] = 0x212 + ( animFrame / 3 ) * 3 ;
spriteDef [ 3 ] = 0x230 + ( animFrame / 3 ) * 3 ;
spriteDef [ 4 ] = 0x231 + ( animFrame / 3 ) * 3 ;
spriteDef [ 5 ] = 0x232 + ( animFrame / 3 ) * 3 ;
spriteDef [ 6 ] = 0x250 + ( animFrame / 3 ) * 3 ;
spriteDef [ 7 ] = 0x251 + ( animFrame / 3 ) * 3 ;
spriteDef [ 8 ] = 0x252 + ( animFrame / 3 ) * 3 ;
}
animFrame + + ;
}
// FurnaceCVFurBallMedium IMPLEMENTATION
void FurnaceCVFurBallMedium : : tick ( ) {
if ( ( animFrame / 3 ) > = 4 ) {
memset ( spriteDef , 0 , 9 * sizeof ( unsigned short ) ) ;
dead = true ;
} else {
spriteDef [ 0 ] = 0x410 + ( animFrame / 3 ) * 3 ;
spriteDef [ 1 ] = 0x411 + ( animFrame / 3 ) * 3 ;
spriteDef [ 2 ] = 0x412 + ( animFrame / 3 ) * 3 ;
spriteDef [ 3 ] = 0x430 + ( animFrame / 3 ) * 3 ;
spriteDef [ 4 ] = 0x431 + ( animFrame / 3 ) * 3 ;
spriteDef [ 5 ] = 0x432 + ( animFrame / 3 ) * 3 ;
spriteDef [ 6 ] = 0x450 + ( animFrame / 3 ) * 3 ;
spriteDef [ 7 ] = 0x451 + ( animFrame / 3 ) * 3 ;
spriteDef [ 8 ] = 0x452 + ( animFrame / 3 ) * 3 ;
}
animFrame + + ;
}
// FurnaceCVFurBallLarge IMPLEMENTATION
void FurnaceCVFurBallLarge : : tick ( ) {
if ( ( animFrame / 3 ) > = 4 ) {
memset ( spriteDef , 0 , 16 * sizeof ( unsigned short ) ) ;
dead = true ;
} else {
for ( int i = 0 ; i < 4 ; i + + ) {
spriteDef [ i < < 2 ] = ( i < < 5 ) + 0x390 + ( ( animFrame / 3 ) < < 2 ) ;
spriteDef [ 1 + ( i < < 2 ) ] = ( i < < 5 ) + 0x391 + ( ( animFrame / 3 ) < < 2 ) ;
spriteDef [ 2 + ( i < < 2 ) ] = ( i < < 5 ) + 0x392 + ( ( animFrame / 3 ) < < 2 ) ;
spriteDef [ 3 + ( i < < 2 ) ] = ( i < < 5 ) + 0x393 + ( ( animFrame / 3 ) < < 2 ) ;
}
}
animFrame + + ;
}
// INSTRUMENTS
static const unsigned char __00_fui [ ] = {
0x46 , 0x49 , 0x4e , 0x53 , 0xc4 , 0x00 , 0x38 , 0x00 , 0x4e , 0x41 , 0x06 , 0x00 ,
0x73 , 0x68 , 0x6f , 0x74 , 0x31 , 0x00 , 0x4d , 0x41 , 0x8c , 0x00 , 0x08 , 0x00 ,
0x00 , 0x0b , 0xff , 0xff , 0x00 , 0x01 , 0x00 , 0x01 , 0x0f , 0x0b , 0x09 , 0x07 ,
0x06 , 0x05 , 0x04 , 0x03 , 0x02 , 0x01 , 0x00 , 0x01 , 0x10 , 0xff , 0xff , 0x00 ,
0xc1 , 0x00 , 0x01 , 0x42 , 0x00 , 0x00 , 0x40 , 0x48 , 0x00 , 0x00 , 0x40 , 0x3c ,
0x00 , 0x00 , 0x40 , 0x36 , 0x00 , 0x00 , 0x40 , 0x32 , 0x00 , 0x00 , 0x40 , 0x2f ,
0x00 , 0x00 , 0x40 , 0x28 , 0x00 , 0x00 , 0x40 , 0x24 , 0x00 , 0x00 , 0x40 , 0x21 ,
0x00 , 0x00 , 0x40 , 0x1f , 0x00 , 0x00 , 0x40 , 0x1f , 0x00 , 0x00 , 0x40 , 0x24 ,
0x00 , 0x00 , 0x40 , 0x24 , 0x00 , 0x00 , 0x40 , 0x24 , 0x00 , 0x00 , 0x40 , 0x24 ,
0x00 , 0x00 , 0x40 , 0x21 , 0x00 , 0x00 , 0x40 , 0x05 , 0x01 , 0xff , 0xff , 0x00 ,
0x01 , 0x00 , 0x01 , 0x01 , 0x0e , 0x01 , 0xff , 0xff , 0x00 , 0x01 , 0x00 , 0x01 ,
0x00 , 0x0f , 0x01 , 0xff , 0xff , 0x00 , 0x01 , 0x00 , 0x01 , 0x0d , 0x10 , 0x01 ,
0xff , 0xff , 0x00 , 0x01 , 0x00 , 0x01 , 0x0e , 0x13 , 0x01 , 0xff , 0xff , 0x00 ,
0x81 , 0x00 , 0x01 , 0xd8 , 0x75 , 0xff , 0x50 , 0x4e , 0x01 , 0x00 , 0x03
} ;
static const unsigned int __00_fui_len = 167 ;
static const unsigned char __01_fui [ ] = {
0x46 , 0x49 , 0x4e , 0x53 , 0xc4 , 0x00 , 0x38 , 0x00 , 0x4e , 0x41 , 0x0c , 0x00 ,
0x65 , 0x78 , 0x70 , 0x6c , 0x31 , 0x20 , 0x28 , 0x47 , 0x2d , 0x35 , 0x29 , 0x00 ,
0x4d , 0x41 , 0xc5 , 0x00 , 0x08 , 0x00 , 0x00 , 0x3a , 0xff , 0xff , 0x00 , 0x01 ,
0x00 , 0x01 , 0x0a , 0x0e , 0x0e , 0x0d , 0x0d , 0x0c , 0x0e , 0x0f , 0x09 , 0x0e ,
0x0d , 0x0e , 0x0d , 0x0c , 0x0c , 0x0c , 0x0b , 0x0b , 0x0b , 0x0a , 0x0a , 0x0a ,
0x0a , 0x09 , 0x09 , 0x09 , 0x08 , 0x08 , 0x08 , 0x08 , 0x08 , 0x07 , 0x07 , 0x07 ,
0x06 , 0x06 , 0x06 , 0x06 , 0x06 , 0x05 , 0x05 , 0x05 , 0x05 , 0x04 , 0x04 , 0x04 ,
0x03 , 0x03 , 0x03 , 0x03 , 0x02 , 0x01 , 0x01 , 0x01 , 0x01 , 0x01 , 0x01 , 0x00 ,
0x01 , 0x25 , 0x06 , 0xff , 0x00 , 0x41 , 0x00 , 0x01 , 0xf5 , 0xe9 , 0xe7 , 0xe5 ,
0xe4 , 0x04 , 0x03 , 0xf9 , 0xf4 , 0x01 , 0xfa , 0x03 , 0xf3 , 0xf2 , 0x00 , 0xf4 ,
0x04 , 0x05 , 0xf8 , 0x00 , 0xf9 , 0x01 , 0xf9 , 0xfc , 0xfc , 0xf7 , 0x02 , 0xff ,
0xf8 , 0x04 , 0x00 , 0xf7 , 0xf7 , 0xff , 0xfa , 0x00 , 0xfb , 0x05 , 0x06 , 0xff ,
0xff , 0x00 , 0x01 , 0x00 , 0x01 , 0x01 , 0x00 , 0x00 , 0x01 , 0x01 , 0x01 , 0x0e ,
0x01 , 0xff , 0xff , 0x00 , 0x01 , 0x00 , 0x01 , 0x01 , 0x0f , 0x06 , 0xff , 0xff ,
0x00 , 0x01 , 0x00 , 0x01 , 0x0a , 0x01 , 0x01 , 0x01 , 0x01 , 0x06 , 0x10 , 0x06 ,
0xff , 0xff , 0x00 , 0x01 , 0x00 , 0x01 , 0x05 , 0x04 , 0x04 , 0x04 , 0x04 , 0x0c ,
0x13 , 0x06 , 0xff , 0xff , 0x00 , 0xc1 , 0x00 , 0x01 , 0xad , 0x3a , 0x00 , 0x00 ,
0xaa , 0xaa , 0x00 , 0x00 , 0xaa , 0xaa , 0x00 , 0x00 , 0xaa , 0xaa , 0x00 , 0x00 ,
0xaa , 0xaa , 0x00 , 0x00 , 0x20 , 0x21 , 0x00 , 0x00 , 0xff , 0x50 , 0x4e , 0x01 ,
0x00 , 0x00
} ;
static const unsigned int __01_fui_len = 230 ;
static const unsigned char __02_fui [ ] = {
0x46 , 0x49 , 0x4e , 0x53 , 0xc4 , 0x00 , 0x38 , 0x00 , 0x4e , 0x41 , 0x0e , 0x00 ,
0x70 , 0x69 , 0x63 , 0x6b , 0x75 , 0x70 , 0x31 , 0x20 , 0x28 , 0x47 , 0x2d , 0x35 ,
0x29 , 0x00 , 0x4d , 0x41 , 0x5d , 0x00 , 0x08 , 0x00 , 0x00 , 0x21 , 0xff , 0xff ,
0x00 , 0x01 , 0x00 , 0x01 , 0x0f , 0x0f , 0x04 , 0x04 , 0x0c , 0x0c , 0x03 , 0x03 ,
0x0a , 0x0a , 0x02 , 0x02 , 0x08 , 0x08 , 0x01 , 0x01 , 0x06 , 0x06 , 0x06 , 0x06 ,
0x04 , 0x04 , 0x04 , 0x04 , 0x02 , 0x02 , 0x02 , 0x02 , 0x01 , 0x01 , 0x01 , 0x01 ,
0x00 , 0x01 , 0x04 , 0x00 , 0xff , 0x00 , 0x01 , 0x00 , 0x04 , 0x00 , 0x04 , 0x07 ,
0x0c , 0x05 , 0x01 , 0xff , 0xff , 0x00 , 0x01 , 0x00 , 0x01 , 0x00 , 0x0e , 0x01 ,
0xff , 0xff , 0x00 , 0x01 , 0x00 , 0x01 , 0x01 , 0x0f , 0x01 , 0xff , 0xff , 0x00 ,
0x01 , 0x00 , 0x01 , 0x01 , 0x13 , 0x01 , 0xff , 0xff , 0x00 , 0x81 , 0x00 , 0x01 ,
0x55 , 0x55 , 0xff , 0x50 , 0x4e , 0x01 , 0x00 , 0x00
} ;
static const unsigned int __02_fui_len = 128 ;
static const unsigned char __03_fui [ ] = {
0x46 , 0x49 , 0x4e , 0x53 , 0xc4 , 0x00 , 0x38 , 0x00 , 0x4e , 0x41 , 0x0e , 0x00 ,
0x70 , 0x69 , 0x63 , 0x6b , 0x75 , 0x70 , 0x32 , 0x20 , 0x28 , 0x41 , 0x2d , 0x35 ,
0x29 , 0x00 , 0x4d , 0x41 , 0x44 , 0x00 , 0x08 , 0x00 , 0x00 , 0x0a , 0xff , 0xff ,
0x00 , 0x01 , 0x00 , 0x01 , 0x0f , 0x0e , 0x04 , 0x0d , 0x0c , 0x03 , 0x02 , 0x02 ,
0x01 , 0x00 , 0x01 , 0x02 , 0x00 , 0xff , 0x00 , 0x01 , 0x00 , 0x03 , 0x00 , 0x07 ,
0x05 , 0x01 , 0xff , 0xff , 0x00 , 0x01 , 0x00 , 0x01 , 0x00 , 0x0e , 0x01 , 0xff ,
0xff , 0x00 , 0x01 , 0x00 , 0x01 , 0x01 , 0x0f , 0x01 , 0xff , 0xff , 0x00 , 0x01 ,
0x00 , 0x01 , 0x01 , 0x13 , 0x01 , 0xff , 0xff , 0x00 , 0x81 , 0x00 , 0x01 , 0x55 ,
0x55 , 0xff , 0x50 , 0x4e , 0x01 , 0x00 , 0x00
} ;
static const unsigned int __03_fui_len = 103 ;
static const unsigned char __04_fui [ ] = {
0x46 , 0x49 , 0x4e , 0x53 , 0xc4 , 0x00 , 0x38 , 0x00 , 0x4e , 0x41 , 0x0f , 0x00 ,
0x64 , 0x65 , 0x61 , 0x74 , 0x68 , 0x20 , 0x63 , 0x31 , 0x20 , 0x28 , 0x43 , 0x2d ,
0x34 , 0x29 , 0x00 , 0x4d , 0x41 , 0xbf , 0x00 , 0x08 , 0x00 , 0x00 , 0x50 , 0xff ,
0xff , 0x00 , 0x01 , 0x00 , 0x01 , 0x0f , 0x0e , 0x0b , 0x09 , 0x0f , 0x0f , 0x0f ,
0x0e , 0x0e , 0x0d , 0x0d , 0x0c , 0x0c , 0x0c , 0x0b , 0x0b , 0x0c , 0x0b , 0x09 ,
0x08 , 0x0d , 0x0d , 0x0c , 0x0c , 0x0b , 0x0b , 0x0b , 0x0a , 0x0a , 0x0a , 0x0a ,
0x09 , 0x09 , 0x09 , 0x08 , 0x08 , 0x09 , 0x09 , 0x08 , 0x08 , 0x07 , 0x07 , 0x06 ,
0x06 , 0x06 , 0x06 , 0x05 , 0x05 , 0x05 , 0x05 , 0x05 , 0x05 , 0x05 , 0x05 , 0x05 ,
0x04 , 0x04 , 0x04 , 0x04 , 0x04 , 0x04 , 0x03 , 0x03 , 0x03 , 0x02 , 0x02 , 0x01 ,
0x01 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x01 , 0x01 , 0x01 , 0x01 , 0x01 , 0x01 ,
0x00 , 0x01 , 0x10 , 0x00 , 0xff , 0x00 , 0x41 , 0x00 , 0x01 , 0xff , 0xf7 , 0xf0 ,
0xef , 0x06 , 0x02 , 0xfd , 0xfb , 0xf7 , 0xf5 , 0xf3 , 0xf1 , 0xf0 , 0xee , 0xec ,
0xec , 0x04 , 0x01 , 0x00 , 0xff , 0x01 , 0x41 , 0x00 , 0x01 , 0xf6 , 0x05 , 0x01 ,
0xff , 0xff , 0x00 , 0x01 , 0x00 , 0x01 , 0x00 , 0x0e , 0x10 , 0x00 , 0xff , 0x00 ,
0x01 , 0x00 , 0x01 , 0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x0f , 0x10 , 0x00 , 0xff , 0x00 ,
0x01 , 0x00 , 0x01 , 0x01 , 0x01 , 0x01 , 0x01 , 0x05 , 0x05 , 0x05 , 0x05 , 0x05 ,
0x05 , 0x05 , 0x05 , 0x05 , 0x05 , 0x05 , 0x05 , 0x13 , 0x01 , 0xff , 0xff , 0x00 ,
0x81 , 0x00 , 0x01 , 0x55 , 0x55 , 0xff , 0x50 , 0x4e , 0x01 , 0x00 , 0x00
} ;
static const unsigned int __04_fui_len = 227 ;
static const unsigned char __05_fui [ ] = {
0x46 , 0x49 , 0x4e , 0x53 , 0xc4 , 0x00 , 0x38 , 0x00 , 0x4e , 0x41 , 0x0f , 0x00 ,
0x64 , 0x65 , 0x61 , 0x74 , 0x68 , 0x20 , 0x63 , 0x32 , 0x20 , 0x28 , 0x43 , 0x2d ,
0x34 , 0x29 , 0x00 , 0x4d , 0x41 , 0xd8 , 0x00 , 0x08 , 0x00 , 0x00 , 0x51 , 0xff ,
0xff , 0x00 , 0x01 , 0x00 , 0x01 , 0x08 , 0x0b , 0x0b , 0x0c , 0x0f , 0x0f , 0x0f ,
0x0e , 0x0e , 0x0d , 0x0d , 0x0c , 0x0c , 0x0c , 0x0b , 0x0b , 0x05 , 0x07 , 0x07 ,
0x07 , 0x09 , 0x09 , 0x09 , 0x08 , 0x08 , 0x08 , 0x08 , 0x07 , 0x07 , 0x07 , 0x07 ,
0x07 , 0x03 , 0x04 , 0x04 , 0x04 , 0x05 , 0x05 , 0x05 , 0x05 , 0x05 , 0x05 , 0x05 ,
0x04 , 0x04 , 0x04 , 0x04 , 0x04 , 0x02 , 0x02 , 0x02 , 0x02 , 0x03 , 0x03 , 0x03 ,
0x03 , 0x03 , 0x03 , 0x03 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x01 , 0x01 , 0x01 ,
0x01 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x01 , 0x01 , 0x01 , 0x01 ,
0x01 , 0x00 , 0x01 , 0x10 , 0x00 , 0xff , 0x00 , 0x01 , 0x00 , 0x01 , 0x36 , 0x15 ,
0x0f , 0x0b , 0x39 , 0x37 , 0x35 , 0x34 , 0x33 , 0x32 , 0x31 , 0x31 , 0x30 , 0x2f ,
0x2f , 0x2e , 0x04 , 0x01 , 0x00 , 0xff , 0x01 , 0x41 , 0x00 , 0x01 , 0xf6 , 0x05 ,
0x01 , 0xff , 0xff , 0x00 , 0x01 , 0x00 , 0x01 , 0x01 , 0x0e , 0x10 , 0x00 , 0xff ,
0x00 , 0x01 , 0x00 , 0x01 , 0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x0f , 0x10 , 0x00 , 0xff ,
0x00 , 0x01 , 0x00 , 0x01 , 0x0d , 0x0d , 0x0d , 0x0d , 0x0d , 0x0d , 0x0d , 0x0d ,
0x0d , 0x0d , 0x0d , 0x0d , 0x0d , 0x0d , 0x0d , 0x0d , 0x10 , 0x10 , 0x00 , 0xff ,
0x00 , 0x01 , 0x00 , 0x01 , 0x0b , 0x0b , 0x0b , 0x0b , 0x0b , 0x0b , 0x0b , 0x0b ,
0x0b , 0x0b , 0x0b , 0x0b , 0x0b , 0x0b , 0x0b , 0x0b , 0x13 , 0x01 , 0xff , 0xff ,
0x00 , 0x81 , 0x00 , 0x01 , 0xf5 , 0x75 , 0xff , 0x50 , 0x4e , 0x01 , 0x00 , 0x00
} ;
static const unsigned int __05_fui_len = 252 ;
static const unsigned char __07_fui [ ] = {
0x46 , 0x49 , 0x4e , 0x53 , 0xc4 , 0x00 , 0x38 , 0x00 , 0x4e , 0x41 , 0x0b , 0x00 ,
0x74 , 0x79 , 0x70 , 0x65 , 0x77 , 0x72 , 0x69 , 0x74 , 0x65 , 0x72 , 0x00 , 0x4d ,
0x41 , 0x4c , 0x00 , 0x08 , 0x00 , 0x00 , 0x04 , 0x00 , 0xff , 0x00 , 0x01 , 0x00 ,
0x01 , 0x06 , 0x05 , 0x04 , 0x00 , 0x01 , 0x01 , 0x00 , 0xff , 0x00 , 0xc1 , 0x00 ,
0x01 , 0x3e , 0x00 , 0x00 , 0x40 , 0x05 , 0x01 , 0xff , 0xff , 0x00 , 0x01 , 0x00 ,
0x01 , 0x00 , 0x0e , 0x04 , 0x00 , 0xff , 0x00 , 0x01 , 0x00 , 0x01 , 0x01 , 0x00 ,
0x00 , 0x00 , 0x0f , 0x01 , 0xff , 0xff , 0x00 , 0x01 , 0x00 , 0x01 , 0x0e , 0x10 ,
0x01 , 0xff , 0xff , 0x00 , 0x01 , 0x00 , 0x01 , 0x07 , 0x13 , 0x01 , 0xff , 0xff ,
0x00 , 0x81 , 0x00 , 0x01 , 0xc5 , 0x55 , 0xff , 0x50 , 0x4e , 0x01 , 0x00 , 0x03
} ;
static const unsigned int __07_fui_len = 108 ;
static const unsigned char __08_fui [ ] = {
0x46 , 0x49 , 0x4e , 0x53 , 0xc4 , 0x00 , 0x38 , 0x00 , 0x4e , 0x41 , 0x12 , 0x00 ,
0x74 , 0x72 , 0x61 , 0x6e , 0x73 , 0x69 , 0x74 , 0x69 , 0x6f , 0x6e , 0x31 , 0x20 ,
0x28 , 0x47 , 0x2d , 0x33 , 0x29 , 0x00 , 0x4d , 0x41 , 0xdf , 0x00 , 0x08 , 0x00 ,
0x00 , 0x5e , 0xff , 0xff , 0x00 , 0x01 , 0x00 , 0x01 , 0x0c , 0x0b , 0x0b , 0x0a ,
0x09 , 0x08 , 0x08 , 0x08 , 0x0f , 0x0d , 0x0d , 0x0c , 0x0b , 0x0b , 0x0a , 0x0a ,
0x0e , 0x0e , 0x0d , 0x0d , 0x0c , 0x0c , 0x0c , 0x0c , 0x0b , 0x0c , 0x0c , 0x0c ,
0x0d , 0x0d , 0x0e , 0x0e , 0x0e , 0x0d , 0x0e , 0x0e , 0x0e , 0x0e , 0x0e , 0x0e ,
0x0e , 0x0e , 0x0e , 0x0e , 0x0e , 0x0e , 0x0e , 0x0e , 0x0d , 0x0d , 0x0c , 0x0c ,
0x0c , 0x0b , 0x0b , 0x0b , 0x0b , 0x0a , 0x0a , 0x09 , 0x08 , 0x08 , 0x08 , 0x07 ,
0x07 , 0x07 , 0x07 , 0x06 , 0x06 , 0x06 , 0x05 , 0x05 , 0x04 , 0x04 , 0x04 , 0x04 ,
0x04 , 0x03 , 0x03 , 0x03 , 0x03 , 0x03 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 ,
0x01 , 0x01 , 0x01 , 0x01 , 0x01 , 0x00 , 0x01 , 0x1b , 0x17 , 0xff , 0x00 , 0x01 ,
0x00 , 0x02 , 0x00 , 0x04 , 0x07 , 0x04 , 0x07 , 0x0c , 0x07 , 0x0c , 0x10 , 0x0c ,
0x10 , 0x13 , 0x10 , 0x13 , 0x18 , 0x13 , 0x18 , 0x1c , 0x18 , 0x1c , 0x1f , 0x1c ,
0x1f , 0x24 , 0x1f , 0x1c , 0x1f , 0x04 , 0x26 , 0x25 , 0xff , 0x01 , 0x01 , 0x00 ,
0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x0e , 0x05 , 0x01 , 0xff , 0xff , 0x00 , 0x01 , 0x00 , 0x01 , 0x00 ,
0x0e , 0x01 , 0xff , 0xff , 0x00 , 0x01 , 0x00 , 0x01 , 0x01 , 0x0f , 0x01 , 0xff ,
0xff , 0x00 , 0x01 , 0x00 , 0x01 , 0x01 , 0x13 , 0x01 , 0xff , 0xff , 0x00 , 0x81 ,
0x00 , 0x01 , 0x55 , 0x55 , 0xff , 0x50 , 0x4e , 0x01 , 0x00 , 0x00
} ;
static const unsigned int __08_fui_len = 262 ;
static const unsigned char __09_fui [ ] = {
0x46 , 0x49 , 0x4e , 0x53 , 0xc4 , 0x00 , 0x38 , 0x00 , 0x4e , 0x41 , 0x12 , 0x00 ,
0x74 , 0x72 , 0x61 , 0x6e , 0x73 , 0x69 , 0x74 , 0x69 , 0x6f , 0x6e , 0x32 , 0x20 ,
0x28 , 0x43 , 0x2d , 0x34 , 0x29 , 0x00 , 0x4d , 0x41 , 0x77 , 0x00 , 0x08 , 0x00 ,
0x00 , 0x3b , 0xff , 0xff , 0x00 , 0x01 , 0x00 , 0x01 , 0x0f , 0x0e , 0x0c , 0x0b ,
0x0a , 0x09 , 0x08 , 0x07 , 0x07 , 0x06 , 0x05 , 0x04 , 0x03 , 0x02 , 0x02 , 0x02 ,
0x0b , 0x0a , 0x09 , 0x08 , 0x07 , 0x06 , 0x06 , 0x05 , 0x05 , 0x04 , 0x03 , 0x03 ,
0x02 , 0x02 , 0x01 , 0x01 , 0x07 , 0x06 , 0x06 , 0x05 , 0x05 , 0x04 , 0x04 , 0x03 ,
0x02 , 0x02 , 0x02 , 0x01 , 0x01 , 0x00 , 0x00 , 0x00 , 0x04 , 0x03 , 0x03 , 0x02 ,
0x02 , 0x02 , 0x01 , 0x01 , 0x01 , 0x01 , 0x00 , 0x01 , 0x04 , 0x00 , 0xff , 0x00 ,
0x01 , 0x00 , 0x01 , 0x04 , 0x07 , 0x0e , 0x12 , 0x05 , 0x01 , 0xff , 0xff , 0x00 ,
0x01 , 0x00 , 0x01 , 0x00 , 0x0e , 0x01 , 0xff , 0xff , 0x00 , 0x01 , 0x00 , 0x01 ,
0x01 , 0x0f , 0x01 , 0xff , 0xff , 0x00 , 0x01 , 0x00 , 0x01 , 0x01 , 0x13 , 0x01 ,
0xff , 0xff , 0x00 , 0x81 , 0x00 , 0x01 , 0x55 , 0x55 , 0xff , 0x50 , 0x4e , 0x01 ,
0x00 , 0x00
} ;
static const unsigned int __09_fui_len = 158 ;
static const unsigned char __0a_fui [ ] = {
0x46 , 0x49 , 0x4e , 0x53 , 0xc4 , 0x00 , 0x38 , 0x00 , 0x4e , 0x41 , 0x0b , 0x00 ,
0x69 , 0x6e , 0x69 , 0x74 , 0x20 , 0x28 , 0x43 , 0x2d , 0x34 , 0x29 , 0x00 , 0x4d ,
0x41 , 0x6a , 0x00 , 0x08 , 0x00 , 0x00 , 0x29 , 0xff , 0xff , 0x00 , 0x01 , 0x00 ,
0x01 , 0x0f , 0x0e , 0x0e , 0x0d , 0x0c , 0x0c , 0x0c , 0x0b , 0x0b , 0x0b , 0x0a ,
0x0a , 0x0a , 0x09 , 0x09 , 0x09 , 0x08 , 0x08 , 0x08 , 0x08 , 0x07 , 0x07 , 0x07 ,
0x07 , 0x06 , 0x06 , 0x06 , 0x06 , 0x06 , 0x05 , 0x05 , 0x05 , 0x05 , 0x04 , 0x04 ,
0x04 , 0x04 , 0x03 , 0x02 , 0x01 , 0x00 , 0x01 , 0x09 , 0x03 , 0xff , 0x00 , 0x01 ,
0x00 , 0x01 , 0x07 , 0x13 , 0x07 , 0x0b , 0x07 , 0x04 , 0x08 , 0x0e , 0x04 , 0x05 ,
0x01 , 0xff , 0xff , 0x00 , 0x01 , 0x00 , 0x01 , 0x00 , 0x0e , 0x01 , 0xff , 0xff ,
0x00 , 0x01 , 0x00 , 0x01 , 0x01 , 0x0f , 0x01 , 0xff , 0xff , 0x00 , 0x01 , 0x00 ,
0x01 , 0x01 , 0x13 , 0x01 , 0xff , 0xff , 0x00 , 0x81 , 0x00 , 0x01 , 0x55 , 0x55 ,
0xff , 0x50 , 0x4e , 0x01 , 0x00 , 0x00
} ;
static const unsigned int __0a_fui_len = 138 ;
static const unsigned char __0b_fui [ ] = {
0x46 , 0x49 , 0x4e , 0x53 , 0xc4 , 0x00 , 0x38 , 0x00 , 0x4e , 0x41 , 0x0e , 0x00 ,
0x72 , 0x65 , 0x73 , 0x70 , 0x61 , 0x77 , 0x6e , 0x20 , 0x28 , 0x43 , 0x2d , 0x34 ,
0x29 , 0x00 , 0x4d , 0x41 , 0x69 , 0x00 , 0x08 , 0x00 , 0x00 , 0x29 , 0xff , 0xff ,
0x00 , 0x01 , 0x00 , 0x01 , 0x0f , 0x0c , 0x0b , 0x0a , 0x05 , 0x0f , 0x0c , 0x0b ,
0x0a , 0x05 , 0x0f , 0x0c , 0x0b , 0x0a , 0x05 , 0x0f , 0x0c , 0x0b , 0x0a , 0x05 ,
0x0f , 0x0c , 0x0b , 0x0a , 0x05 , 0x0f , 0x0c , 0x0b , 0x0a , 0x05 , 0x0f , 0x0c ,
0x0b , 0x08 , 0x05 , 0x0f , 0x0d , 0x0b , 0x09 , 0x05 , 0x00 , 0x01 , 0x08 , 0x08 ,
0xff , 0x00 , 0x01 , 0x00 , 0x05 , 0x10 , 0x0f , 0x0d , 0x15 , 0x14 , 0x0d , 0x0f ,
0x10 , 0x05 , 0x01 , 0xff , 0xff , 0x00 , 0x01 , 0x00 , 0x01 , 0x00 , 0x0e , 0x01 ,
0xff , 0xff , 0x00 , 0x01 , 0x00 , 0x01 , 0x01 , 0x0f , 0x01 , 0xff , 0xff , 0x00 ,
0x01 , 0x00 , 0x01 , 0x01 , 0x13 , 0x01 , 0xff , 0xff , 0x00 , 0x81 , 0x00 , 0x01 ,
0x55 , 0x55 , 0xff , 0x50 , 0x4e , 0x01 , 0x00 , 0x00
} ;
static const unsigned int __0b_fui_len = 140 ;
static const unsigned char __0c_fui [ ] = {
0x46 , 0x49 , 0x4e , 0x53 , 0xc4 , 0x00 , 0x39 , 0x00 , 0x4e , 0x41 , 0x09 , 0x00 ,
0x74 , 0x61 , 0x6e , 0x6b , 0x6d , 0x6f , 0x76 , 0x65 , 0x00 , 0x4d , 0x41 , 0x92 ,
0x01 , 0x08 , 0x00 , 0x00 , 0xff , 0x0b , 0xff , 0x00 , 0x01 , 0x00 , 0x01 , 0x04 ,
0x05 , 0x07 , 0x07 , 0x07 , 0x06 , 0x06 , 0x06 , 0x05 , 0x05 , 0x05 , 0x04 , 0x04 ,
0x04 , 0x04 , 0x04 , 0x05 , 0x04 , 0x05 , 0x05 , 0x05 , 0x04 , 0x05 , 0x05 , 0x04 ,
0x04 , 0x04 , 0x05 , 0x04 , 0x04 , 0x05 , 0x04 , 0x05 , 0x05 , 0x04 , 0x05 , 0x04 ,
0x05 , 0x05 , 0x05 , 0x04 , 0x05 , 0x05 , 0x04 , 0x05 , 0x05 , 0x04 , 0x04 , 0x05 ,
0x05 , 0x05 , 0x04 , 0x04 , 0x05 , 0x05 , 0x04 , 0x05 , 0x05 , 0x05 , 0x04 , 0x05 ,
0x05 , 0x04 , 0x05 , 0x04 , 0x04 , 0x04 , 0x04 , 0x05 , 0x04 , 0x05 , 0x05 , 0x05 ,
0x04 , 0x05 , 0x04 , 0x05 , 0x04 , 0x05 , 0x05 , 0x05 , 0x04 , 0x05 , 0x05 , 0x05 ,
0x05 , 0x05 , 0x05 , 0x04 , 0x05 , 0x05 , 0x04 , 0x04 , 0x05 , 0x05 , 0x04 , 0x05 ,
0x05 , 0x04 , 0x05 , 0x05 , 0x04 , 0x04 , 0x04 , 0x04 , 0x04 , 0x05 , 0x04 , 0x04 ,
0x04 , 0x05 , 0x05 , 0x04 , 0x04 , 0x05 , 0x04 , 0x05 , 0x04 , 0x05 , 0x04 , 0x05 ,
0x04 , 0x04 , 0x05 , 0x05 , 0x05 , 0x05 , 0x04 , 0x04 , 0x04 , 0x05 , 0x04 , 0x04 ,
0x04 , 0x04 , 0x04 , 0x04 , 0x05 , 0x04 , 0x04 , 0x05 , 0x05 , 0x05 , 0x04 , 0x04 ,
0x04 , 0x04 , 0x05 , 0x05 , 0x05 , 0x05 , 0x04 , 0x05 , 0x05 , 0x04 , 0x04 , 0x04 ,
0x05 , 0x04 , 0x05 , 0x05 , 0x04 , 0x05 , 0x05 , 0x04 , 0x05 , 0x04 , 0x04 , 0x05 ,
0x04 , 0x04 , 0x04 , 0x04 , 0x05 , 0x04 , 0x04 , 0x04 , 0x04 , 0x05 , 0x05 , 0x05 ,
0x05 , 0x05 , 0x04 , 0x04 , 0x05 , 0x04 , 0x05 , 0x05 , 0x05 , 0x04 , 0x04 , 0x05 ,
0x05 , 0x04 , 0x05 , 0x04 , 0x04 , 0x05 , 0x05 , 0x04 , 0x05 , 0x04 , 0x04 , 0x04 ,
0x04 , 0x04 , 0x04 , 0x05 , 0x04 , 0x05 , 0x04 , 0x05 , 0x05 , 0x05 , 0x05 , 0x04 ,
0x05 , 0x04 , 0x05 , 0x04 , 0x04 , 0x04 , 0x05 , 0x05 , 0x04 , 0x04 , 0x04 , 0x04 ,
0x05 , 0x05 , 0x04 , 0x04 , 0x05 , 0x05 , 0x05 , 0x04 , 0x05 , 0x05 , 0x05 , 0x05 ,
0x05 , 0x05 , 0x04 , 0x04 , 0x04 , 0x04 , 0x04 , 0x04 , 0x04 , 0x04 , 0x04 , 0x05 ,
0x04 , 0x04 , 0x01 , 0x02 , 0x00 , 0xff , 0x00 , 0x41 , 0x00 , 0x01 , 0xf4 , 0xce ,
0x04 , 0x10 , 0xff , 0xff , 0x00 , 0x81 , 0x00 , 0x01 , 0xb8 , 0x00 , 0xd9 , 0x00 ,
0x02 , 0x01 , 0x18 , 0x01 , 0xd7 , 0x00 , 0xa3 , 0x00 , 0x79 , 0x00 , 0x59 , 0x00 ,
0x3e , 0x00 , 0x2b , 0x00 , 0x1b , 0x00 , 0x0f , 0x00 , 0x05 , 0x00 , 0xfe , 0xff ,
0xfe , 0xff , 0xf5 , 0xff , 0x05 , 0x01 , 0xff , 0xff , 0x00 , 0x01 , 0x00 , 0x01 ,
0x00 , 0x06 , 0x02 , 0x00 , 0xff , 0x00 , 0x01 , 0x00 , 0x01 , 0x52 , 0x00 , 0x07 ,
0x02 , 0x00 , 0xff , 0x00 , 0x01 , 0x00 , 0x01 , 0x15 , 0x00 , 0x0e , 0x01 , 0xff ,
0xff , 0x00 , 0x01 , 0x00 , 0x01 , 0x01 , 0x0f , 0x02 , 0x00 , 0xff , 0x00 , 0x01 ,
0x00 , 0x01 , 0x02 , 0x0d , 0x10 , 0x02 , 0x00 , 0xff , 0x00 , 0x01 , 0x00 , 0x01 ,
0x0c , 0x0a , 0x11 , 0x01 , 0xff , 0xff , 0x00 , 0x01 , 0x00 , 0x01 , 0x01 , 0x12 ,
0x01 , 0xff , 0xff , 0x00 , 0x01 , 0x00 , 0x01 , 0x0b , 0x13 , 0x01 , 0x00 , 0xff ,
0x00 , 0x81 , 0x00 , 0x01 , 0xaa , 0x5a , 0xff , 0x50 , 0x4e , 0x01 , 0x00 , 0x00
} ;
static const unsigned int __0c_fui_len = 432 ;
static const unsigned char __0d_fui [ ] = {
0x46 , 0x49 , 0x4e , 0x53 , 0xc4 , 0x00 , 0x39 , 0x00 , 0x4e , 0x41 , 0x0b , 0x00 ,
0x76 , 0x6f , 0x72 , 0x74 , 0x65 , 0x78 , 0x6d , 0x6f , 0x76 , 0x65 , 0x00 , 0x4d ,
0x41 , 0x68 , 0x00 , 0x08 , 0x00 , 0x00 , 0x10 , 0xff , 0xff , 0x00 , 0x01 , 0x00 ,
0x01 , 0x0a , 0x0a , 0x09 , 0x08 , 0x07 , 0x07 , 0x06 , 0x06 , 0x07 , 0x08 , 0x09 ,
0x0b , 0x0b , 0x0c , 0x0c , 0x00 , 0x01 , 0x0f , 0xff , 0xff , 0x00 , 0x01 , 0x00 ,
0x01 , 0x00 , 0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 , 0x08 , 0x09 , 0x0a ,
0x0b , 0x0c , 0x0d , 0x0e , 0x05 , 0x01 , 0xff , 0xff , 0x00 , 0x01 , 0x00 , 0x01 ,
0x00 , 0x06 , 0x01 , 0xff , 0xff , 0x00 , 0x01 , 0x00 , 0x01 , 0x3a , 0x07 , 0x01 ,
0xff , 0xff , 0x00 , 0x01 , 0x00 , 0x01 , 0x00 , 0x0e , 0x01 , 0xff , 0xff , 0x00 ,
0x01 , 0x00 , 0x01 , 0x01 , 0x11 , 0x01 , 0xff , 0xff , 0x00 , 0x01 , 0x00 , 0x01 ,
0x01 , 0x12 , 0x01 , 0xff , 0xff , 0x00 , 0x01 , 0x00 , 0x01 , 0x00 , 0xff , 0x50 ,
0x4e , 0x01 , 0x00 , 0x00
} ;
static const unsigned int __0d_fui_len = 136 ;
static const unsigned char __0e_fui [ ] = {
0x46 , 0x49 , 0x4e , 0x53 , 0xc4 , 0x00 , 0x39 , 0x00 , 0x4e , 0x41 , 0x0c , 0x00 ,
0x76 , 0x6f , 0x72 , 0x74 , 0x65 , 0x78 , 0x73 , 0x68 , 0x6f , 0x6f , 0x74 , 0x00 ,
0x4d , 0x41 , 0xc1 , 0x00 , 0x08 , 0x00 , 0x00 , 0x3c , 0xff , 0xff , 0x00 , 0x01 ,
0x00 , 0x01 , 0x0f , 0x0f , 0x0f , 0x0f , 0x0f , 0x0f , 0x0f , 0x0f , 0x0f , 0x0f ,
0x0f , 0x0f , 0x0f , 0x0f , 0x0f , 0x0f , 0x0f , 0x0f , 0x0f , 0x0f , 0x0f , 0x0f ,
0x0f , 0x0f , 0x0f , 0x0f , 0x0f , 0x0f , 0x0f , 0x0e , 0x0e , 0x0d , 0x0d , 0x0c ,
0x0c , 0x0b , 0x0b , 0x0b , 0x0a , 0x0a , 0x09 , 0x09 , 0x08 , 0x08 , 0x07 , 0x07 ,
0x06 , 0x06 , 0x05 , 0x05 , 0x05 , 0x04 , 0x04 , 0x03 , 0x03 , 0x03 , 0x02 , 0x02 ,
0x01 , 0x00 , 0x01 , 0x3c , 0xff , 0xff , 0x00 , 0x41 , 0x00 , 0x01 , 0x0b , 0x09 ,
0x0b , 0x07 , 0x0b , 0x05 , 0x0b , 0x03 , 0x0b , 0x01 , 0x0b , 0xfe , 0x0b , 0xfc ,
0x0b , 0xfa , 0x0b , 0x05 , 0x0b , 0x04 , 0x0b , 0x03 , 0x0b , 0x02 , 0x0b , 0x01 ,
0x0b , 0x00 , 0x0b , 0xff , 0x0b , 0xfe , 0x0b , 0xfd , 0x0b , 0xfc , 0x0b , 0xfb ,
0x0b , 0xfa , 0x0b , 0xf9 , 0x0b , 0xf7 , 0x0b , 0xf6 , 0x0b , 0xf5 , 0x0b , 0xf4 ,
0x0b , 0xf3 , 0x0b , 0xf2 , 0x0b , 0xf1 , 0x0b , 0xef , 0x0b , 0xee , 0x05 , 0x01 ,
0x00 , 0xff , 0x00 , 0x01 , 0x00 , 0x01 , 0x0c , 0x06 , 0x01 , 0xff , 0xff , 0x00 ,
0x01 , 0x00 , 0x01 , 0xff , 0x07 , 0x01 , 0xff , 0xff , 0x00 , 0x01 , 0x00 , 0x01 ,
0x04 , 0x0e , 0x01 , 0x00 , 0xff , 0x00 , 0x01 , 0x00 , 0x01 , 0x01 , 0x11 , 0x01 ,
0xff , 0xff , 0x00 , 0x01 , 0x00 , 0x01 , 0x01 , 0x12 , 0x01 , 0xff , 0xff , 0x00 ,
0x01 , 0x00 , 0x01 , 0x00 , 0xff , 0x50 , 0x4e , 0x01 , 0x00 , 0x00
} ;
static const unsigned int __0e_fui_len = 226 ;
static const unsigned char __06_fui [ ] = {
0x46 , 0x49 , 0x4e , 0x53 , 0xc4 , 0x00 , 0x38 , 0x00 , 0x4d , 0x41 , 0xbf , 0x00 ,
0x08 , 0x00 , 0x00 , 0x1c , 0xff , 0xff , 0x00 , 0x01 , 0x00 , 0x01 , 0x0f , 0x0e ,
0x0c , 0x0c , 0x0c , 0x0b , 0x0b , 0x0a , 0x0a , 0x0a , 0x09 , 0x09 , 0x08 , 0x08 ,
0x08 , 0x08 , 0x07 , 0x07 , 0x07 , 0x07 , 0x06 , 0x05 , 0x04 , 0x03 , 0x02 , 0x01 ,
0x01 , 0x00 , 0x01 , 0x15 , 0xff , 0xff , 0x00 , 0xc1 , 0x00 , 0x01 , 0x5d , 0x00 ,
0x00 , 0x40 , 0x63 , 0x00 , 0x00 , 0x40 , 0x35 , 0x00 , 0x00 , 0x40 , 0x35 , 0x00 ,
0x00 , 0x40 , 0x31 , 0x00 , 0x00 , 0x40 , 0x2e , 0x00 , 0x00 , 0x40 , 0x2b , 0x00 ,
0x00 , 0x40 , 0x29 , 0x00 , 0x00 , 0x40 , 0x27 , 0x00 , 0x00 , 0x40 , 0x26 , 0x00 ,
0x00 , 0x40 , 0x24 , 0x00 , 0x00 , 0x40 , 0x23 , 0x00 , 0x00 , 0x40 , 0x22 , 0x00 ,
0x00 , 0x40 , 0x1e , 0x00 , 0x00 , 0x40 , 0x1d , 0x00 , 0x00 , 0x40 , 0x1c , 0x00 ,
0x00 , 0x40 , 0x1b , 0x00 , 0x00 , 0x40 , 0x1a , 0x00 , 0x00 , 0x40 , 0x1a , 0x00 ,
0x00 , 0x40 , 0x19 , 0x00 , 0x00 , 0x40 , 0x18 , 0x00 , 0x00 , 0x40 , 0x05 , 0x03 ,
0x04 , 0x04 , 0x00 , 0x01 , 0x00 , 0x01 , 0x01 , 0x01 , 0x00 , 0x0e , 0x01 , 0x01 ,
0x04 , 0x00 , 0x01 , 0x00 , 0x01 , 0x01 , 0x0f , 0x03 , 0x04 , 0x04 , 0x00 , 0x01 ,
0x00 , 0x01 , 0x0d , 0x0d , 0x01 , 0x10 , 0x01 , 0xff , 0xff , 0x00 , 0x01 , 0x00 ,
0x01 , 0x0e , 0x13 , 0x03 , 0x05 , 0x04 , 0x00 , 0xc1 , 0x00 , 0x01 , 0xd8 , 0x75 ,
0x00 , 0x00 , 0xaa , 0xea , 0x00 , 0x00 , 0xaa , 0xaa , 0x00 , 0x00 , 0xff , 0x50 ,
0x4e , 0x01 , 0x00 , 0x00
} ;
static const unsigned int __06_fui_len = 208 ;
static const unsigned char __0f_fui [ ] = {
0x46 , 0x49 , 0x4e , 0x53 , 0xc4 , 0x00 , 0x38 , 0x00 , 0x4d , 0x41 , 0x54 , 0x00 ,
0x08 , 0x00 , 0x00 , 0x0b , 0xff , 0xff , 0x00 , 0x01 , 0x00 , 0x01 , 0x0f , 0x09 ,
0x06 , 0x04 , 0x04 , 0x03 , 0x03 , 0x02 , 0x01 , 0x01 , 0x00 , 0x01 , 0x02 , 0x00 ,
0xff , 0x00 , 0xc1 , 0x00 , 0x02 , 0x3e , 0x00 , 0x00 , 0x40 , 0x4e , 0x00 , 0x00 ,
0x40 , 0x05 , 0x01 , 0xff , 0xff , 0x00 , 0x01 , 0x00 , 0x01 , 0x00 , 0x0e , 0x01 ,
0x06 , 0xff , 0x00 , 0x01 , 0x00 , 0x01 , 0x01 , 0x0f , 0x01 , 0xff , 0xff , 0x00 ,
0x01 , 0x00 , 0x01 , 0x04 , 0x10 , 0x01 , 0xff , 0xff , 0x00 , 0x01 , 0x00 , 0x01 ,
0x09 , 0x13 , 0x01 , 0xff , 0xff , 0x00 , 0x81 , 0x00 , 0x01 , 0xc5 , 0x55 , 0xff ,
0x50 , 0x4e , 0x01 , 0x00 , 0x03
} ;
static const unsigned int __0f_fui_len = 101 ;
# define LOAD_INS(x,y) { \
DivInstrument * newIns = new DivInstrument ; \
SafeReader reader ( x , y ) ; \
newIns - > readInsData ( reader , DIV_ENGINE_VERSION , & e - > song ) ; \
newIns - > std . volMacro . speed * = macroMul ; \
newIns - > std . arpMacro . speed * = macroMul ; \
newIns - > std . dutyMacro . speed * = macroMul ; \
newIns - > std . waveMacro . speed * = macroMul ; \
newIns - > std . pitchMacro . speed * = macroMul ; \
newIns - > std . phaseResetMacro . speed * = macroMul ; \
newIns - > std . ex1Macro . speed * = macroMul ; \
newIns - > std . ex2Macro . speed * = macroMul ; \
newIns - > std . ex3Macro . speed * = macroMul ; \
newIns - > std . ex4Macro . speed * = macroMul ; \
newIns - > std . ex5Macro . speed * = macroMul ; \
newIns - > std . ex6Macro . speed * = macroMul ; \
newIns - > std . ex7Macro . speed * = macroMul ; \
newIns - > std . ex8Macro . speed * = macroMul ; \
e - > addInstrumentPtr ( newIns ) ; \
}
void FurnaceCV : : loadInstruments ( ) {
logV ( " loadInstruments " ) ;
fxInsBase = e - > song . ins . size ( ) ;
fxChanBase = e - > getTotalChannelCount ( ) ;
int macroMul = ( int ) ( ( e - > curSubSong - > hz + 20.0 ) / 60.0 ) ;
int sys = e - > song . systemLen ;
if ( e - > addSystem ( DIV_SYSTEM_POWERNOISE ) ) {
if ( e - > song . masterVol < 0.1 ) {
e - > song . systemVol [ sys ] = 12.0 ;
} else {
e - > song . systemVol [ sys ] = 1.2 / e - > song . masterVol ;
}
}
LOAD_INS ( __00_fui , __00_fui_len ) ;
LOAD_INS ( __01_fui , __01_fui_len ) ;
LOAD_INS ( __02_fui , __02_fui_len ) ;
LOAD_INS ( __03_fui , __03_fui_len ) ;
LOAD_INS ( __04_fui , __04_fui_len ) ;
LOAD_INS ( __05_fui , __05_fui_len ) ;
LOAD_INS ( __06_fui , __06_fui_len ) ;
LOAD_INS ( __07_fui , __07_fui_len ) ;
LOAD_INS ( __08_fui , __08_fui_len ) ;
LOAD_INS ( __09_fui , __09_fui_len ) ;
LOAD_INS ( __0a_fui , __0a_fui_len ) ;
LOAD_INS ( __0b_fui , __0b_fui_len ) ;
LOAD_INS ( __0c_fui , __0c_fui_len ) ;
LOAD_INS ( __0d_fui , __0d_fui_len ) ;
LOAD_INS ( __0e_fui , __0e_fui_len ) ;
LOAD_INS ( __0f_fui , __0f_fui_len ) ;
}
// FurnaceCVMine IMPLEMENTATION
void FurnaceCVMine : : collision ( FurnaceCVObject * other ) {
if ( other - > type = = CV_BULLET | | other - > type = = CV_PLAYER ) {
dead = true ;
cv - > createObject < FurnaceCVExplMedium > ( x - 4 , y - 4 ) ;
cv - > soundEffect ( SE_EXPL1 ) ;
cv - > addScore ( rand ( ) % 50 ) ;
}
}
// FurnaceCVPowerupP IMPLEMENTATION
void FurnaceCVPowerupP : : collision ( FurnaceCVObject * other ) {
if ( other - > type = = CV_PLAYER ) {
dead = true ;
cv - > shotType = 1 ;
cv - > soundEffect ( SE_PICKUP2 ) ;
cv - > addScore ( 200 ) ;
}
}
void FurnaceCVPowerupP : : tick ( ) {
if ( - - life = = 0 ) dead = true ;
if ( life > 64 | | ( life & 1 ) ) {
spriteDef [ 0 ] = 0x490 ;
spriteDef [ 1 ] = 0x491 ;
spriteDef [ 2 ] = 0x4b0 ;
spriteDef [ 3 ] = 0x4b1 ;
} else {
spriteDef [ 0 ] = 0 ;
spriteDef [ 1 ] = 0 ;
spriteDef [ 2 ] = 0 ;
spriteDef [ 3 ] = 0 ;
}
}
// FurnaceCVPowerupS IMPLEMENTATION
void FurnaceCVPowerupS : : collision ( FurnaceCVObject * other ) {
if ( other - > type = = CV_PLAYER ) {
dead = true ;
cv - > shotType = 2 ;
cv - > soundEffect ( SE_PICKUP2 ) ;
cv - > addScore ( 200 ) ;
}
}
void FurnaceCVPowerupS : : tick ( ) {
if ( - - life = = 0 ) dead = true ;
if ( life > 64 | | ( life & 1 ) ) {
spriteDef [ 0 ] = 0x492 ;
spriteDef [ 1 ] = 0x493 ;
spriteDef [ 2 ] = 0x4b2 ;
spriteDef [ 3 ] = 0x4b3 ;
} else {
spriteDef [ 0 ] = 0 ;
spriteDef [ 1 ] = 0 ;
spriteDef [ 2 ] = 0 ;
spriteDef [ 3 ] = 0 ;
}
}
// FurnaceCVExtraLife IMPLEMENTATION
void FurnaceCVExtraLife : : collision ( FurnaceCVObject * other ) {
if ( other - > type = = CV_PLAYER ) {
dead = true ;
cv - > soundEffect ( SE_PICKUP1 ) ;
cv - > lives + + ;
}
}
void FurnaceCVExtraLife : : tick ( ) {
if ( - - life = = 0 ) dead = true ;
if ( life > 64 | | ( life & 1 ) ) {
spriteDef [ 0 ] = 0x0c ;
spriteDef [ 1 ] = 0x0d ;
spriteDef [ 2 ] = 0x2c ;
spriteDef [ 3 ] = 0x2d ;
} else {
spriteDef [ 0 ] = 0 ;
spriteDef [ 1 ] = 0 ;
spriteDef [ 2 ] = 0 ;
spriteDef [ 3 ] = 0 ;
}
}
// FurnaceCVEnemyVortex IMPLEMENTATION
void FurnaceCVEnemyVortex : : collision ( FurnaceCVObject * other ) {
if ( other - > type = = CV_BULLET | | other - > type = = CV_PLAYER ) {
dead = true ;
if ( ( rand ( ) % 2 ) = = 0 ) {
switch ( rand ( ) % 10 ) {
case 0 :
cv - > createObject < FurnaceCVExtraLife > ( x , y ) ;
break ;
case 1 : case 2 : case 3 : case 4 :
cv - > createObject < FurnaceCVPowerupP > ( x , y ) ;
break ;
case 5 : case 6 : case 7 : case 8 : case 9 :
cv - > createObject < FurnaceCVPowerupS > ( x , y ) ;
break ;
}
}
cv - > soundEffect ( SE_EXPL1 ) ;
cv - > createObject < FurnaceCVFurBallMedium > ( x - 4 , y - 4 ) ;
cv - > addScore ( 1000 ) ;
}
}
void FurnaceCVEnemyVortex : : tick ( ) {
x + = speedX ;
y + = speedY ;
animFrame + = 0x08 ;
if ( - - nextTime = = 0 ) {
nextTime = 10 + ( rand ( ) % 160 ) ;
speedX = ( rand ( ) % 5 ) - 2 ;
speedY = ( rand ( ) % 5 ) - 2 ;
cv - > soundEffect ( SE_VORTEXMOVE ) ;
}
if ( - - shootTime = = 0 ) {
shootTime = 6 + ( rand ( ) % 100 ) ;
cv - > soundEffect ( SE_VORTEXSHOOT ) ;
for ( int i = 0 ; i < 6 + cv - > stage ; i + + ) {
float fraction = ( float ) i / ( float ) ( 5 + cv - > stage ) ;
float xs = cos ( fraction * M_PI * 2.0 ) * 28 ;
float ys = sin ( fraction * M_PI * 2.0 ) * 28 ;
FurnaceCVEnemyBullet * b = cv - > createObject < FurnaceCVEnemyBullet > ( x + 4 , y + 4 ) ;
b - > setType ( 1 ) ;
b - > speedX = xs ;
b - > speedY = ys ;
}
}
if ( HITS_BORDER ) {
CONFINE_TO_BORDER ;
}
spriteDef [ 0 ] = 0x480 + ( ( animFrame > > 5 ) < < 1 ) ;
spriteDef [ 1 ] = 0x481 + ( ( animFrame > > 5 ) < < 1 ) ;
spriteDef [ 2 ] = 0x4a0 + ( ( animFrame > > 5 ) < < 1 ) ;
spriteDef [ 3 ] = 0x4a1 + ( ( animFrame > > 5 ) < < 1 ) ;
}