diff options
| -rwxr-xr-x | include/game.h | 205 | ||||
| -rw-r--r-- | include/newer.h | 1 | ||||
| -rw-r--r-- | kamek_pal.x | 17 | ||||
| -rw-r--r-- | src/koopatlas/hud.cpp | 471 | ||||
| -rw-r--r-- | src/koopatlas/hud.h | 45 | ||||
| -rw-r--r-- | src/koopatlas/pathmanager.cpp | 23 | ||||
| -rw-r--r-- | src/koopatlas/pathmanager.h | 2 | ||||
| -rw-r--r-- | src/koopatlas/shop.cpp | 22 | ||||
| -rw-r--r-- | src/koopatlas/starcoin.cpp | 26 | ||||
| -rw-r--r-- | src/newer.cpp | 21 | ||||
| -rw-r--r-- | src/palaceDude.cpp | 2 | ||||
| -rw-r--r-- | src/replay.S | 6 | ||||
| -rw-r--r-- | src/switchblock.S | 6 | 
13 files changed, 466 insertions, 381 deletions
diff --git a/include/game.h b/include/game.h index 4695ea6..e31e675 100755 --- a/include/game.h +++ b/include/game.h @@ -80,9 +80,60 @@ struct StartLevelInfo {  	unsigned char level2; // 0x0F
  };
 -extern void *GameMgr;
 +class GMgr8 {
 +	public:
 +		virtual ~GMgr8();
 +
 +		int _4;
 +		float _8, _C;
 +		u32 _10, _14;
 +		u8 _18, _19, _1A, _1B, _1C;
 +		u32 _20, _24, _28, _2C, _30;
 +};
 +
 +struct GMgrA0 {
 +	u32 _0, _4, _8;
 +	u8 _C;
 +};
 +
 +class GameMgr {
 +	public:
 +		virtual ~GameMgr();
 +
 +		u32 _4;
 +		GMgr8 eight;
 +		u32 _3C, _40, _44, _48, _4C, _50, _54, _58;
 +		u32 _5C, _60, _64, _68, _6C;
 +		u32 _70[10];
 +		u8 _98;
 +		u32 _9C;
 +		GMgrA0 _A0[40];
 +		u32 _320[10], _348[10];
 +		u32 _370, _374, _378, _37C;
 +		u8 switchPalaceFlag;
 +		u32 CharIDs[4];
 +		u8 _394;
 +		u8 _395[10];
 +		u8 _39F[10];
 +		u8 _3A9[10];
 +		u8 _3B3;
 +		u32 numberToInsertInThing[7];
 +		u32 msgCategory, msgID;
 +		u8 _3D8;
 +		u8 currentControllerType, layoutShadowFlag;
 +		u32 numberToInsertInThing10, numberToInsertInThing11;
 +		u32 _3E4, _3E8, _3EC, _3F0, _3F4, _3F8;
 +		// unmapped data from 3FC..AEC (0x6F0)
 +		u8 _3FC[0x6F0];
 +		u32 _AEC, _AF0, _AF4, _AF8;
 +		u8 _AFC, _AFD, _AFE[88];
 +		u8 _B56[4];
 +		u8 _B5A, _B5B;
 +};
 +
 +extern GameMgr *GameMgrP;
  inline void *GetGameMgr() {
 -	return GameMgr;
 +	return GameMgrP;
  }
  bool QueryPlayerAvailability(int id);
 @@ -219,9 +270,31 @@ inline SaveHandler *GetSaveHandler() {  #define WPAD_MINUS	0x1000
  #define WPAD_HOME	0x8000
 +struct Remocon {
 +	virtual ~Remocon();
 +	int id;
 +	int controllerType;
 +	u32 untouchedButtons;
 +	u32 lastUntouchedButtons;
 +	u32 heldButtons;
 +	u32 lastHeldButtons;
 +	u32 nowPressed;
 +	u32 _20, _24, _28, _2C, _30;
 +	Vec acc, lastAcc;
 +	Vec2 accVertical, lastAccVertical;
 +	Vec2 vec_5C, lastVec_5C;
 +	Vec2 vec_6C;
 +	Vec2 vec_74, lastVec_74;
 +	float wiimoteMoveDistanceOrSomething;
 +	float lastWiimoteMoveDistanceOrSomething;
 +	u8 isShaking, _8D;
 +	u16 tiltAmount;
 +	u8 _90, _91, _92;
 +};
 +
  struct RemoconMngClass {
  	void *vtable;
 -	void *controllers[4];
 +	Remocon *controllers[4];
  };
  /*
 @@ -246,7 +319,7 @@ inline int GetActiveWiimoteID() {  	return ActiveWiimoteID;
  }
 -inline void *GetActiveRemocon() {
 +inline Remocon *GetActiveRemocon() {
  	return GetRemoconMng()->controllers[GetActiveWiimoteID()];
  }
 @@ -254,11 +327,11 @@ inline void *GetActiveWiimote() {  	return ActiveWiimote;
  }
 -inline unsigned int Remocon_GetButtons(void *self) {
 +inline unsigned int Remocon_GetButtons(Remocon *self) {
  	return *((unsigned int*)((u32)self+0x18));
  }
 -inline unsigned int Remocon_GetPressed(void *self) {
 +inline unsigned int Remocon_GetPressed(Remocon *self) {
  	return *((unsigned int*)((u32)self+0x1C));
  }
 @@ -505,6 +578,20 @@ namespace lyt {  	class Group;
  	class GroupContainer;
 +	namespace detail {
 +		class TexCoordAry {
 +			public:
 +				TexCoordAry();
 +				void Free();
 +				void Reserve(u8 count);
 +				void SetSize(u8 count);
 +				void Copy(const void *source, u8 count);
 +
 +				u8 reservedSize, usedSize;
 +				void *data;
 +		};
 +	}
 +
  	class Layout {
  	public:
  		Layout();
 @@ -636,11 +723,17 @@ namespace lyt {  		u8 flag;
  		char name[0x11];
 -		char userdata[8];
 +		char userdata[9];
 -		u8 _D5;
  		u8 paneIsOwnedBySomeoneElse;
  		u8 _D7;
 +
 +		void SetVisible(bool value) {
 +			if (value)
 +				flag |= 1;
 +			else
 +				flag &= ~1;
 +		}
  	};
  	class TextBox : public Pane {
 @@ -657,7 +750,7 @@ namespace lyt {  		uchar GetVtxColorElement(ulong id) const;
  		void SetVtxColorElement(ulong id, uchar value);
 -		virtual void LoadMtx(const DrawInfo &info);
 +		void LoadMtx(const DrawInfo &info);
  		virtual void AllocStringBuffer(u16 size);
  		virtual void FreeStringBuffer();
 @@ -681,6 +774,26 @@ namespace lyt {  		u8 alignment;
  		u8 flags;
  	};
 +
 +	class Picture : public Pane {
 +	public:
 +		Picture(void *, void *); // todo: Picture((res::Picture const *,ResBlockSet const &))
 +		~Picture();
 +
 +		void *GetRuntimeTypeInfo() const;
 +
 +		void DrawSelf(const DrawInfo &info);
 +
 +		ut::Color GetVtxColor(ulong id) const;
 +		void SetVtxColor(ulong id, ut::Color color);
 +		uchar GetVtxColorElement(ulong id) const;
 +		void SetVtxColorElement(ulong id, uchar value);
 +
 +		virtual void Append(const GXTexObj &obj);
 +
 +		ut::Color colours[4];
 +		detail::TexCoordAry texCoords;
 +	};
  }
 @@ -2487,7 +2600,10 @@ namespace nw4r {  				void SetupGXWithColorMapping(Color c1, Color c2);
  			public:
 -				Color colors[8]; // todo: document
 +				Color minColMapping, maxColMapping;
 +				Color vtxColours[4];
 +				Color topColour, bottomColour;
 +
  				u32 modeOfSomeKind;
  				float scaleX;
  				float scaleY;
 @@ -2522,12 +2638,12 @@ namespace nw4r {  				bool IsDrawFlagSet(ulong, ulong) const;
 -				float _4C;
 +				float widthLimit;
  				float charSpace;
 -				float somethingRelatedToLineHeight;
 -				u32 _58;
 +				float lineSpace;
 +				u32 tabWidth;
  				u32 drawFlag;
 -				void *tagProcessorMaybe;
 +				void *tagProcessor;
  		};
  	}
  }
 @@ -2667,7 +2783,7 @@ namespace m2d {  		nw4r::lyt::Pane *getRootPane();
  		nw4r::lyt::Pane *findPaneByName(const char *name) const;
  		nw4r::lyt::TextBox *findTextBoxByName(const char *name) const;
 -		nw4r::lyt::Pane *findPictureByName(const char *name) const; // TODO: change to others
 +		nw4r::lyt::Picture *findPictureByName(const char *name) const;
  		nw4r::lyt::Pane *findWindowByName(const char *name) const;
  		void animate();
 @@ -2705,10 +2821,10 @@ namespace m2d {  		// does NSMBW even use consts? I have no idea. maybe not
 -		void getPanes(const char **names, nw4r::lyt::Pane *output, int count) const;
 -		void getWindows(const char **names, nw4r::lyt::Pane *output, int count) const; // TODO: change to others
 -		void getPictures(const char **names, nw4r::lyt::Pane *output, int count) const;
 -		void getTextBoxes(const char **names, nw4r::lyt::TextBox *output, int count) const;
 +		void getPanes(const char **names, nw4r::lyt::Pane **output, int count) const;
 +		void getWindows(const char **names, nw4r::lyt::Pane **output, int count) const; // TODO: change to others
 +		void getPictures(const char **names, nw4r::lyt::Picture **output, int count) const;
 +		void getTextBoxes(const char **names, nw4r::lyt::TextBox **output, int count) const;
  		void setLangStrings(const char **names, const int *msgIDs, int category, int count);
 @@ -3072,6 +3188,57 @@ namespace mHeap {  };
  void WriteNumberToTextBox(int *number, const int *fieldLength, nw4r::lyt::TextBox *textBox, bool unk); // 800B3B60
 +
 +namespace EGG {
 +	class MsgRes {
 +		private:
 +			const u8 *bmg, *INF1, *DAT1, *STR1, *MID1, *FLW1, *FLI1;
 +		public:
 +			MsgRes(const u8 *bmgFile, u32 unusedParam); // 802D7970
 +			virtual ~MsgRes();
 +
 +			static void parseFormatCode(wchar_t initialTag, const wchar_t *string, u8 *outArgsSize, u32 *outCmd, const wchar_t **args); // 802D7B10
 +
 +			const wchar_t *findStringForMessageID(int category, int message) const; // 0x802D7B50
 +
 +		private:
 +			void setBMG(const u8 *ptr); // 802D7B90
 +			void setINF(const u8 *ptr); // 802D7BA0
 +			void setDAT(const u8 *ptr); // 802D7BB0
 +			void setSTR(const u8 *ptr); // 802D7BC0
 +			void setMID(const u8 *ptr); // 802D7BD0
 +			void setFLW(const u8 *ptr); // 802D7BE0
 +			void setFLI(const u8 *ptr); // 802D7BF0
 +			int identifySectionByMagic(u32 magic) const; // 802D7C00
 +
 +		protected:
 +			struct INFEntry {
 +				u32 stringOffset;
 +			};
 +			const INFEntry *findINFForMessageID(int category, int message) const; // 802D7C90
 +			u32 getEntryFromMID(int index) const; // 802D7D70
 +	};
 +}
 +namespace dScript {
 +	class Res_c : public EGG::MsgRes {
 +		public:
 +			Res_c(const u8 *bmgFile, u32 unusedParam); // 800CE7F0
 +			~Res_c();
 +
 +			u16 getCharScaleForMessageID(int category, int message) const; // 800CE890
 +			u8 getFontIDForMessageID(int category, int message) const; // 800CE8C0
 +	};
 +}
 +class MessageClass {
 +	public:
 +		dDvdLoader_c loader;
 +		void *rawBmgPointer;
 +		dScript::Res_c *msgRes;
 +};
 +
 +dScript::Res_c *GetBMG(); // 800CDD50
 +void WriteBMGToTextBox(nw4r::lyt::TextBox *textBox, dScript::Res_c *res, int category, int message, int argCount, ...); // 0x800C9B50
 +
  extern "C" dAc_Py_c* GetSpecificPlayerActor(int number);
  extern "C" dStageActor_c *CreateActor(u16 classID, int settings, Vec pos, char rot, char layer);
  extern "C" dStageActor_c *Actor_SearchByID(u32 actorID);
 diff --git a/include/newer.h b/include/newer.h index 4f34f81..d98f290 100644 --- a/include/newer.h +++ b/include/newer.h @@ -27,5 +27,6 @@ enum NWRWorld {  NWRWorld NewerWorldForLevelID(int world, int level);  const wchar_t *NewerWorldName(NWRWorld world); +int getStarCoinCount();  #endif /* NEWER_H */ diff --git a/kamek_pal.x b/kamek_pal.x index 6f7db85..75613ad 100644 --- a/kamek_pal.x +++ b/kamek_pal.x @@ -11,12 +11,17 @@ SECTIONS {  	__dt__18BGGMEffectRendererFv = 0x80092E30;  	__vt__18BGGMEffectRenderer = 0x80311908;  	__construct_array = 0x802DCC90; + +	GetBMG__Fv = 0x800CDD50; +	WriteBMGToTextBox__FPQ34nw4r3lyt7TextBoxPQ27dScript5Res_ciiie = 0x800C9B50; +  	m2d__Anm_c__Load = 0x801644F0;  	m2d__AnmResHandler_c__Load = 0x80163FA0;  	RealAcPyDtor = 0x80144820;  	InsertIntIntoTextBox1 = 0x800B3BE0; +	WriteNumberToTextBox__FPiPCiPQ34nw4r3lyt7TextBoxb = 0x800B3B60;  	__ct__20daJrClownForPlayer_cFv = 0x80810480;  	__dt__20daJrClownForPlayer_cFv = 0x80810540; /* Beans indeed. */ @@ -747,9 +752,15 @@ SECTIONS {  	findTextBoxByName__Q23m2d17EmbedLayoutBase_cCFPCc = 0x80007320;  	findPictureByName__Q23m2d17EmbedLayoutBase_cCFPCc = 0x800073D0;  	findWindowByName__Q23m2d17EmbedLayoutBase_cCFPCc = 0x80007470; +  	__ct__Q23m2d13EmbedLayout_cFv = 0x800C89A0;  	__dt__Q23m2d13EmbedLayout_cFv = 0x800C89F0;  	loadArc__Q23m2d13EmbedLayout_cFPCcb = 0x800C8D00; +	getPanes__Q23m2d13EmbedLayout_cCFPPCcPPQ34nw4r3lyt4Panei = 0x800C8E50; +	getWindows__Q23m2d13EmbedLayout_cCFPPCcPPQ34nw4r3lyt6Windowi = 0x800C8EC0; +	getPictures__Q23m2d13EmbedLayout_cCFPPCcPPQ34nw4r3lyt7Picturei = 0x800C8F30; +	getTextBoxes__Q23m2d13EmbedLayout_cCFPPCcPPQ34nw4r3lyt7TextBoxi = 0x800C8FA0; +	setLangStrings__Q23m2d13EmbedLayout_cFPPCcPCiii = 0x800C9010;  	loadAnimations__Q23m2d13EmbedLayout_cFPPCci = 0x800C90A0;  	loadGroups__Q23m2d13EmbedLayout_cFPPCcPii = 0x800C91E0;  	enableNonLoopAnim__Q23m2d13EmbedLayout_cFib = 0x800C93E0; @@ -760,7 +771,11 @@ SECTIONS {  	isAnyAnimOn__Q23m2d13EmbedLayout_cFv = 0x800C9730;  	free__Q23m2d13EmbedLayout_cFv = 0x800C9A20;  	execAnimations__Q23m2d13EmbedLayout_cFv = 0x800C9650; +  	attachArc__Q23m2d8ResAcc_cFPvPCc = 0x801637A0; + +	setSpeed__Q23m2d11FrameCtrl_cFf = 0x80163920; +  	scheduleForDrawing__Q23m2d6Base_cFv = 0x80163990;  	RenderEffects__Fii = 0x80093F10; @@ -968,7 +983,7 @@ SECTIONS {  	ArchiveHeap = 0x8042A72C;  	DVDClass = 0x8042A318; -	GameMgr = 0x8042A25C; +	GameMgrP = 0x8042A25C;  	SaveFileInstance = 0x8042A320;  	SaveHandlerInstance = 0x8042A298;  	RemoconMng = 0x8042A230; diff --git a/src/koopatlas/hud.cpp b/src/koopatlas/hud.cpp index 44b0fce..c9124d2 100644 --- a/src/koopatlas/hud.cpp +++ b/src/koopatlas/hud.cpp @@ -1,28 +1,5 @@  #include "koopatlas/hud.h" -void CharToWChar(const char *input, wchar_t *output, int length) { for (int i = 0; i < length; i++) output[i] = input[i]; } - -int getStarCoinCount() { - -	SaveBlock *save = GetSaveFile()->GetBlock(-1); -	int coinsSpent = save->credits_hiscore; -	int coinsEarned = 0; - -	for (int w = 0; w < 10; w++) { -		for (int l = 0; l < 10; l++) { -			u32 conds = save->GetLevelCondition(w, l); - -			if (conds & COND_COIN1) { coinsEarned++; } -			if (conds & COND_COIN2) { coinsEarned++; } -			if (conds & COND_COIN3) { coinsEarned++; } -		} -	} - -	int coinsLeft = coinsEarned - coinsSpent; -	return coinsLeft; -} - -  dWMHud_c *dWMHud_c::instance = 0;  dWMHud_c *dWMHud_c::build() { @@ -37,27 +14,22 @@ dWMHud_c *dWMHud_c::build() {  dWMHud_c::dWMHud_c() {  	layoutLoaded = false; +	displayedControllerType = -1;  } +enum WMHudAnimation { +	SHOW_LIVES = 0, +	SHOW_HEADER, +	SHOW_FOOTER +}; -// TODO: Need to define these in a better way, somehow -#define ANIM_BUTTON_1 0 -#define ANIM_BUTTON_2 1 -#define ANIM_BOTTOM_SHOW 2 -#define ANIM_BOTTOM_HIDE 3 -#define ANIM_TOP_SHOW 4 -#define ANIM_TOP_HIDE 5  int dWMHud_c::onCreate() {  	if (!layoutLoaded) { -		bool gotFile = layout.loadArc("maphud.arc", false); +		bool gotFile = layout.loadArc("MapHUD.arc", false);  		if (!gotFile)  			return false; -		//static const char *brlanNames[3] = {"maphud_hitbutton.brlan", "maphud_in.brlan", "maphud_out.brlan"}; -		static const char *brlanNames[5] = {"maphud_hitbutton.brlan", "bottom_in.brlan", "bottom_out.brlan", "top_in.brlan", "top_out.brlan"}; -		static const char *groupNames[6] = {"B01_Button", "B02_Button", "A00_Window", "A00_Window", "A01_Window", "A01_Window"}; -  		bool output = layout.build("maphud.brlyt");  		if (!IsWideScreen()) { @@ -70,19 +42,53 @@ int dWMHud_c::onCreate() {  			layout.layout.rootPane->scale.y = 0.7711f;  		} -		layout.loadAnimations(brlanNames, 5); -		layout.loadGroups(groupNames, (int[6]){0, 0, 1, 2, 3, 4}, 6); -		layout.disableAllAnimations(); -		layout.enableNonLoopAnim(ANIM_BOTTOM_SHOW); +		static const char *brlanNames[2] = {"MapHUD_ShowMain.brlan", "MapHUD_ShowHeader.brlan"}; +		static const char *groupNames[3] = {"G_Lives", "G_Header", "G_Footer"}; -		hidePointBar(); -		setWorldText(" "); -		setWorldName(); +		layout.loadAnimations(brlanNames, 2); +		layout.loadGroups(groupNames, (int[3]){0, 1, 0}, 3); +		layout.disableAllAnimations(); -		if (dScKoopatlas_c::instance->pathManager.mustComplainToMapCreator) -			dWMHud_c::instance->setLevelText("Please Fix Your Missing Entrance. Thanks"); +		layout.enableNonLoopAnim(SHOW_LIVES); +		layout.enableNonLoopAnim(SHOW_FOOTER); +		layout.resetAnim(SHOW_HEADER); + +		static const char *tbNames[2] = {"MenuButtonInfo", "ItemsButtonInfo"}; +		layout.setLangStrings(tbNames, (int[2]){12, 15}, 4, 2); + +		static const char *paneNames[] = { +			"N_IconPos1P_00", "N_IconPos2P_00", +			"N_IconPos3P_00", "N_IconPos4P_00" +		}; +		layout.getPanes(paneNames, &N_IconPosXP_00[0], 4); + +		static const char *pictureNames[] = { +			"Header_Centre", "Header_Right", +			"NormalExitFlag", "SecretExitFlag", +			"StarCoinOn0", "StarCoinOn1", "StarCoinOn2", +			"P_marioFace_00", "P_luigiFace_00", +			"P_BkinoFace_00", "P_YkinoFace_00" +		}; +		layout.getPictures(pictureNames, &Header_Centre, 11); + +		static const char *textBoxNames[] = { +			"LevelName", "LevelNameS", +			"LevelNumber", "LevelNumberS", +			"WorldName", "WorldNameS", +			"StarCoinCounter", +			"T_lifeNumber_00", "T_lifeNumber_01", +			"T_lifeNumber_02", "T_lifeNumber_03" +		}; +		layout.getTextBoxes(textBoxNames, &LevelName, 11);  		layoutLoaded = true; + +		willShowHeader = false; + +		if (!dScKoopatlas_c::instance->pathManager.isMoving) +			enteredNode(); + +		setupLives();  	}  	return true; @@ -90,15 +96,24 @@ int dWMHud_c::onCreate() {  int dWMHud_c::onDelete() { +	if (!layoutLoaded) +		return true; +  	return layout.free();  }  int dWMHud_c::onExecute() { -	updateLives(); -	setWorldName(); -	checkPointStatus(); -	setPointName(); +	if (!layoutLoaded) +		return true; + +	if (willShowHeader && (!(layout.isAnimOn(SHOW_HEADER)))) { +		willShowHeader = false; +		loadHeaderInfo(); +		playShowHeaderAnim(); +	} + +	updatePressableButtonThingies();  	layout.execAnimations();  	layout.update(); @@ -108,303 +123,177 @@ int dWMHud_c::onExecute() {  int dWMHud_c::onDraw() { +	if (!layoutLoaded) +		return true; +  	layout.scheduleForDrawing();  	return true;  } -void dWMHud_c::updateLives() { - -	static const char *textID[4] = {"M", "L", "B", "Y"}; -	static const char *picID[4] = {"P_mariopic", "P_luigipic", "P_toadBlue", "P_toadyellow"}; -	for (int i = 0; i < 4; i++) { - -		char boxName [13]; -		sprintf(boxName, "T_%slifes_01", textID[i]); -		nw4r::lyt::TextBox *box = layout.findTextBoxByName(boxName); -		nw4r::lyt::Pane *pic = layout.findPictureByName(picID[i]); -		if (Player_Active[i] != 0) { -			box->alpha = 0xFF; -			pic->alpha = 0xFF; +void dWMHud_c::playShowHeaderAnim() { +	if (!this || !this->layoutLoaded) return; -			char lives [3]; -			sprintf(lives, "%02d", Player_Lives[Player_ID[i]]); -			const char *loaves = lives; -			wchar_t life; +	layout.enableNonLoopAnim(SHOW_HEADER); +} -			CharToWChar(loaves, &life, 3); +void dWMHud_c::playHideHeaderAnim() { +	if (!this || !this->layoutLoaded) return; -			box->SetString(&life); -		} -		else { -			box->alpha = 0; -			pic->alpha = 0; -		} +	if (!layout.isAnimOn(SHOW_HEADER)) { +		layout.enableNonLoopAnim(SHOW_HEADER, true);  	} +	layout.grpHandlers[SHOW_HEADER].frameCtrl.flags = 3; // NO_LOOP | REVERSE +} -	nw4r::lyt::TextBox *coinbox = layout.findTextBoxByName("T_coin_count_01"); - -	char stars [4]; -	int starCoinCount = getStarCoinCount(); -	sprintf(stars, "%03d", starCoinCount); -	const char *scoins = stars; -	wchar_t wcoins; -	CharToWChar(scoins, &wcoins, 4); +void dWMHud_c::loadHeaderInfo() { +	dLevelInfo_c *levelInfo = &dScKoopatlas_c::instance->levelInfo; -	coinbox->SetString(&wcoins); -} +	dLevelInfo_c::entry_s *infEntry = levelInfo->search( +			nodeForHeader->levelNumber[0]-1, nodeForHeader->levelNumber[1]-1); -void dWMHud_c::setLevelText(const char *str, int length) { -	if (str == 0) { -		setLevelText("--NULL STRING--"); +	if (infEntry == 0) { +		LevelName->SetString(L"Unknown Level Name!"); +		LevelNameS->SetString(L"Unknown Level Name!");  		return;  	} -	if (length == -1) { -		length = strlen(str); +	// LEVEL NAME +	wchar_t convertedLevelName[100]; +	const char *sourceLevelName = levelInfo->getNameForLevel(infEntry); +	int charCount = 0; +	 +	while (*sourceLevelName != 0 && charCount < 99) { +		convertedLevelName[charCount] = *sourceLevelName; +		sourceLevelName++; +		charCount++;  	} - -	wchar_t newString[128]; - -	int i; -	for (i = 0; i < length && i < 128; i++) { -		newString[i] = str[i]; +	convertedLevelName[charCount] = 0; + +	LevelName->SetString(convertedLevelName); +	LevelNameS->SetString(convertedLevelName); + +	// LEVEL NUMBER +	wchar_t levelNumber[6]; +	levelNumber[0] = '0' + nodeForHeader->levelNumber[0]; +	levelNumber[1] = '-'; +	if (nodeForHeader->levelNumber[1] >= 10) { +		levelNumber[2] = '0' + (nodeForHeader->levelNumber[1] / 10); +		levelNumber[3] = '0' + (nodeForHeader->levelNumber[1] % 10); +		levelNumber[4] = 0; +	} else { +		levelNumber[2] = '0' + nodeForHeader->levelNumber[1]; +		levelNumber[3] = 0;  	} -	newString[i] = 0; - -	setLevelText(newString, i); -} -void dWMHud_c::setLevelText(const wchar_t *str, int length) { -	if (str == 0) { -		setLevelText("--NULL STRING--"); -		return; -	} +	LevelNumber->SetString(levelNumber); +	LevelNumberS->SetString(levelNumber); -	if (length == -1) { -		length = wcslen(str); -	} +	// INFO +	int w = nodeForHeader->levelNumber[0] - 1; +	int l = nodeForHeader->levelNumber[1] - 1; -	nw4r::lyt::TextBox *box = layout.findTextBoxByName("T_levelname_01"); +	u32 conds = GetSaveFile()->GetBlock(-1)->GetLevelCondition(w, l); +	NormalExitFlag->SetVisible(conds & COND_NORMAL); +	SecretExitFlag->SetVisible(conds & COND_SECRET); +	StarCoinOn[0]->SetVisible(conds & COND_COIN1); +	StarCoinOn[1]->SetVisible(conds & COND_COIN2); +	StarCoinOn[2]->SetVisible(conds & COND_COIN3); +	// SIZE THING  	nw4r::ut::TextWriter tw; -	tw.font = box->font; -	tw.SetFontSize(box->fontSizeX, box->fontSizeY); -	tw.somethingRelatedToLineHeight = box->lineSpace; -	tw.charSpace = box->charSpace; -	if (box->tagProc != 0) -		tw.tagProcessorMaybe = box->tagProc; - -	float width = tw.CalcStringWidth(str, length); -	//SpammyReport("Text width: %f\n", width); - -	layout.findWindowByName("W_levelname")->size.x = width + 22; -	layout.findPictureByName("P_topleftboxbg")->size.x = width; -	layout.findPictureByName("P_topthinboxbg")->size.x = 597 - width; - -	box->SetString(str); +	tw.font = LevelName->font; +	tw.SetFontSize(LevelName->fontSizeX, LevelName->fontSizeY); +	tw.lineSpace = LevelName->lineSpace; +	tw.charSpace = LevelName->charSpace; +	if (LevelName->tagProc != 0) +		tw.tagProcessor = LevelName->tagProc; + +	float width = tw.CalcStringWidth(convertedLevelName, charCount); +	float totalWidth = width + LevelName->trans.x - 20.0f; +	if (totalWidth < 270.0f) +		totalWidth = 270.0f; +	Header_Centre->size.x = totalWidth; +	Header_Right->trans.x = totalWidth;  } -void dWMHud_c::setPointName() { -	// figure this out... -	dKPNode_s *node = dScKoopatlas_c::instance->pathManager.currentNode; -	if (node->type == dKPNode_s::LEVEL) { -		dLevelInfo_c *li = &dScKoopatlas_c::instance->levelInfo; -		dLevelInfo_c::entry_s *entry = li->search(node->levelNumber[0] - 1, node->levelNumber[1] - 1); +void dWMHud_c::enteredNode(dKPNode_s *node) { +	if (node == 0) +		node = dScKoopatlas_c::instance->pathManager.currentNode; -		setLevelText(li->getNameForLevel(entry)); -	} else { -		setLevelText("   "); -		hidePointBar(); +	if (node->type == dKPNode_s::LEVEL) { +		willShowHeader = true; +		nodeForHeader = node;  	}  } -void dWMHud_c::checkPointStatus() { -	dKPNode_s *node = dScKoopatlas_c::instance->pathManager.currentNode; - -	if ((node->type == dKPNode_s::LEVEL) && ((node->levelNumber[1] < 30) || (node->levelNumber[1] > 37))) { -		SaveBlock *save = GetSaveFile()->GetBlock(-1); -		 -		int world = node->levelNumber[0]; -		int level = node->levelNumber[1]; - -		u32 conds = save->GetLevelCondition(world-1, level-1); -		nw4r::lyt::Pane *pic; - -		if (conds & COND_COIN1) { -			pic = layout.findPictureByName("P_coin_on_01"); -			pic->alpha = 0xFF; - -			pic = layout.findPictureByName("P_coin_off_01"); -			pic->alpha = 0; -		} -		else { -			pic = layout.findPictureByName("P_coin_on_01"); -			pic->alpha = 0; - -			pic = layout.findPictureByName("P_coin_off_01"); -			pic->alpha = 0xFF; -		} - -		if (conds & COND_COIN2) { -			pic = layout.findPictureByName("P_coin_on_02"); -			pic->alpha = 0xFF; - -			pic = layout.findPictureByName("P_coin_off_02"); -			pic->alpha = 0; -		} -		else { -			pic = layout.findPictureByName("P_coin_on_02"); -			pic->alpha = 0; - -			pic = layout.findPictureByName("P_coin_off_02"); -			pic->alpha = 0xFF; -		} +void dWMHud_c::leftNode() { +	if (layout.grpHandlers[SHOW_HEADER].frameCtrl.currentFrame > 0.1f) { +		// not hidden -		if (conds & COND_COIN3) { -			pic = layout.findPictureByName("P_coin_on_03"); -			pic->alpha = 0xFF; - -			pic = layout.findPictureByName("P_coin_off_03"); -			pic->alpha = 0; -		} -		else { -			pic = layout.findPictureByName("P_coin_on_03"); -			pic->alpha = 0; - -			pic = layout.findPictureByName("P_coin_off_03"); -			pic->alpha = 0xFF; -		} - -		if (conds & COND_NORMAL) { -			pic = layout.findPictureByName("P_normalexitflag"); -			pic->alpha = 0xFF; -		} -		else { -			pic = layout.findPictureByName("P_normalexitflag"); -			pic->alpha = 0; +		if ((layout.isAnimOn(SHOW_HEADER) && (layout.grpHandlers[SHOW_HEADER].frameCtrl.flags & 2)) +				|| (!layout.isAnimOn(SHOW_HEADER))) { +			// currently being shown, OR fully shown already +			playHideHeaderAnim();  		} - -		if (conds & COND_SECRET) { -			pic = layout.findPictureByName("P_secretexitflag"); -			pic->alpha = 0xFF; -		} -		else { -			pic = layout.findPictureByName("P_secretexitflag"); -			pic->alpha = 0; -		} - -		u8 deaths = save->death_counts[world-1][level-1]; -		nw4r::lyt::TextBox *deathbox = layout.findTextBoxByName("T_death_01"); - -		char die [4]; -		sprintf(die, "%03d", deaths); -		const char *dies = die; -		wchar_t wdie; -		CharToWChar(dies, &wdie, 4); -		deathbox->SetString(&wdie); - -	} else { -		nw4r::lyt::Pane *pic; - -		static const char *picNames[8] = {"P_coin_on_01", "P_coin_off_01", "P_coin_on_02", "P_coin_off_02",  -										  "P_coin_on_03", "P_coin_off_03", "P_normalexitflag", "P_secretexitflag"}; - -		for (int i = 0; i < 8; i++) { -			pic = layout.findPictureByName(picNames[i]); -			pic->alpha = 0; -		} - -		nw4r::lyt::TextBox *deathbox = layout.findTextBoxByName("T_death_01"); -		wchar_t noDie; -		CharToWChar("---", &noDie, 4); -		deathbox->SetString(&noDie);  	}  } -void dWMHud_c::setWorldText(const char *str, int length) { -	if (str == 0) { -		setWorldText("--NULL STRING--"); -		return; -	} - -	if (length == -1) { -		length = strlen(str); -	} - -	wchar_t newString[128]; - -	int i; -	for (i = 0; i < length && i < 128; i++) { -		newString[i] = str[i]; -	} -	newString[i] = 0; -	setWorldText(newString, i); -} - -void dWMHud_c::setWorldText(const wchar_t *str, int length) { -	if (str == 0) { -		setWorldText("--NULL STRING--"); -		return; -	} - -	if (length == -1) { -		length = wcslen(str); -	} -	nw4r::lyt::TextBox *box = layout.findTextBoxByName("T_area_01"); +void dWMHud_c::setupLives() { +	static const int LogicalPlayerIDs[] = {0,1,3,2}; -	nw4r::ut::TextWriter tw; -	tw.font = box->font; -	tw.SetFontSize(box->fontSizeX, box->fontSizeY); -	tw.somethingRelatedToLineHeight = box->lineSpace; -	tw.charSpace = box->charSpace; -	if (box->tagProc != 0) -		tw.tagProcessorMaybe = box->tagProc; +	P_marioFace_00->SetVisible(false); +	P_luigiFace_00->SetVisible(false); +	P_BkinoFace_00->SetVisible(false); +	P_YkinoFace_00->SetVisible(false); -	float width = tw.CalcStringWidth(str, length); -	//SpammyReport("Text width: %f\n", width); +	int playerCount = 0; -	box->SetString(str); -} +	for (int i = 0; i < 4; i++) { +		// The part in setupLives() +		int playerID = LogicalPlayerIDs[i]; +		int slotID = SearchForIndexOfPlayerID(playerID); +		int lives = Player_Lives[slotID]; +		int length = 2; -void dWMHud_c::setWorldName() { -	// figure this out... -	dKPNode_s *node = dScKoopatlas_c::instance->pathManager.currentNode; +		WriteNumberToTextBox(&lives, &length, T_lifeNumber[slotID], true); -	if (node->type == dKPNode_s::LEVEL) { -		int world = node->levelNumber[0]; -		int level = node->levelNumber[1]; +		// The part in setupIconThings() +		if (QueryPlayerAvailability(slotID)) { +			playerCount++; -		setWorldText(NewerWorldName(NewerWorldForLevelID(world, level))); +			nw4r::lyt::Pane *facePane = (&P_marioFace_00)[playerID]; +			facePane->trans = N_IconPosXP_00[i]->trans; +			facePane->SetVisible(true); +		}  	} -} -void dWMHud_c::showPointBar() { -	dKPNode_s *node = dScKoopatlas_c::instance->pathManager.currentNode; - -	if (node->type == dKPNode_s::LEVEL) { -		isPointBarShown = true; - -		layout.enableNonLoopAnim(ANIM_TOP_SHOW); -	} +	for (int i = 0; i < 4; i++) +		N_IconPosXP_00[i]->SetVisible(false); +	N_IconPosXP_00[playerCount - 1]->SetVisible(true);  } +void dWMHud_c::updatePressableButtonThingies() { +	int cntType = RemoconMng->controllers[0]->controllerType; + +	if (cntType != displayedControllerType) { +		displayedControllerType = cntType; -void dWMHud_c::hidePointBar() { -	if (isPointBarShown) { -		isPointBarShown = false; +		int beef = (cntType == 0) ? 0 : 1; +		GameMgrP->currentControllerType = beef; -		layout.enableNonLoopAnim(ANIM_TOP_HIDE); +		WriteBMGToTextBox( +				layout.findTextBoxByName("ItemsButtonInfo"), +				GetBMG(), 4, 15, 0);  	}  } - diff --git a/src/koopatlas/hud.h b/src/koopatlas/hud.h index 347fcb4..e507aea 100644 --- a/src/koopatlas/hud.h +++ b/src/koopatlas/hud.h @@ -15,25 +15,42 @@ class dWMHud_c : public dBase_c {  		bool layoutLoaded;  		m2d::EmbedLayout_c layout; -		void updateLives(); +		static dWMHud_c *build(); +		static dWMHud_c *instance; -		void showPointBar(); -		void hidePointBar(); +		void enteredNode(dKPNode_s *node = 0); +		void leftNode(); -		void setPointName(); -		void checkPointStatus(); -		void setLevelText(const char *str, int length = -1); -		void setLevelText(const wchar_t *str, int length = -1); +		void setupLives(); -		void setWorldName(); -		void setWorldText(const char *str, int length = -1); -		void setWorldText(const wchar_t *str, int length = -1); +	private: +		void playShowHeaderAnim(); +		void playHideHeaderAnim(); +		void loadHeaderInfo(); -		static dWMHud_c *build(); -		static dWMHud_c *instance; +		bool willShowHeader; +		dKPNode_s *nodeForHeader; -	private: -		bool isPointBarShown; +		int displayedControllerType; +		void updatePressableButtonThingies(); + + +		nw4r::lyt::Pane +			*N_IconPosXP_00[4]; + +		nw4r::lyt::Picture +			*Header_Centre, *Header_Right, +			*NormalExitFlag, *SecretExitFlag, +			*StarCoinOn[3], +			*P_marioFace_00, *P_luigiFace_00, +			*P_BkinoFace_00, *P_YkinoFace_00; + +		nw4r::lyt::TextBox +			*LevelName, *LevelNameS, +			*LevelNumber, *LevelNumberS, +			*WorldName, *WorldNameS, +			*StarCoinCounter, +			*T_lifeNumber[4];  };  #endif diff --git a/src/koopatlas/pathmanager.cpp b/src/koopatlas/pathmanager.cpp index 2b85aaa..536b43a 100644 --- a/src/koopatlas/pathmanager.cpp +++ b/src/koopatlas/pathmanager.cpp @@ -372,10 +372,12 @@ void dWMPathManager_c::execute() {  void dWMPathManager_c::startMovementTo(dKPPath_s *path) {  	SpammyReport("moving to path %p [%d,%d to %d,%d]\n", path, path->start->x, path->start->y, path->end->x, path->end->y); -	dWMHud_c::instance->hidePointBar(); -	SpammyReport("point bar hidden\n");  	if (!path->isAvailable) { return; } +	if (currentNode) +		dWMHud_c::instance->leftNode(); + +	calledEnteredNode = false;  	SpammyReport("a\n");  	isMoving = true; @@ -549,6 +551,18 @@ void dWMPathManager_c::moveThroughPath() {  	player->pos.x += move.x;  	player->pos.y -= move.y; +	// what distance is left? +	if (to->type == dKPNode_s::LEVEL && !calledEnteredNode) { +		Vec toEndVec = {to->x - player->pos.x, to->y + player->pos.y, 0.0f}; +		float distToEnd = VECMag(&toEndVec); +		//OSReport("Distance: %f; To:%d,%d; Player:%f,%f; Diff:%f,%f\n", distToEnd, to->x, to->y, player->pos.x, player->pos.y, toEndVec.x, toEndVec.y); + +		if (distToEnd < 64.0f) { +			calledEnteredNode = true; +			dWMHud_c::instance->enteredNode(to); +		} +	} +  	// Check if we've reached the end yet  	if (  			(((move.x > 0) ? (player->pos.x >= to->x) : (player->pos.x <= to->x)) && @@ -621,6 +635,8 @@ void dWMPathManager_c::moveThroughPath() {  			SaveBlock *save = GetSaveFile()->GetBlock(-1);  			save->current_path_node = pathLayer->findNodeID(to); +			if (!calledEnteredNode) +				dWMHud_c::instance->enteredNode();  			if (to->type == dKPNode_s::LEVEL) {  				NWRWorld nWorld = NewerWorldForLevelID(to->levelNumber[0], to->levelNumber[1]); @@ -628,9 +644,6 @@ void dWMPathManager_c::moveThroughPath() {  					save->currentNewerWorld = (u8)nWorld;  				}  			} - -			dWMHud_c::instance->showPointBar(); -			SpammyReport("Point bar shown\n");  		} else {  			startMovementTo(to->getOppositeAvailableExitTo(currentPath));  			SpammyReport("passthrough node, continuing to next path\n"); diff --git a/src/koopatlas/pathmanager.h b/src/koopatlas/pathmanager.h index 4604fc7..5579f66 100644 --- a/src/koopatlas/pathmanager.h +++ b/src/koopatlas/pathmanager.h @@ -62,6 +62,8 @@ class dWMPathManager_c {  		bool evaluateUnlockCondition(u8 *&in, SaveBlock *save, int stack);  		bool isEnteringLevel; + +		bool calledEnteredNode;  		int levelStartWait;  		dLevelInfo_c::entry_s *enteredLevel;  }; diff --git a/src/koopatlas/shop.cpp b/src/koopatlas/shop.cpp index 211ab49..cd20ddb 100644 --- a/src/koopatlas/shop.cpp +++ b/src/koopatlas/shop.cpp @@ -1,26 +1,6 @@  #include "koopatlas/shop.h" -int getStarCoinCountShop() { -	SaveBlock *save = GetSaveFile()->GetBlock(-1); -	int coinsSpent = save->credits_hiscore; -	int coinsEarned = 0; - -	for (int w = 0; w < 10; w++) { -		for (int l = 0; l < 10; l++) { -			u32 conds = save->GetLevelCondition(w, l); - -			if (conds & COND_COIN1) { coinsEarned++; } -			if (conds & COND_COIN2) { coinsEarned++; } -			if (conds & COND_COIN3) { coinsEarned++; } -		} -	} - -	int coinsLeft = coinsEarned - coinsSpent; -	return coinsLeft; -} - -  const char* Produce[10][4] = {   	{ "I_kinoko", 		"g3d/I_kinoko.brres", 			"I_kinoko", 			"wait2" },  	{ "I_fireflower", 	"g3d/I_fireflower.brres", 		"I_fireflower", 		"wait2" }, @@ -381,7 +361,7 @@ void dWMShop_c::BuyItem(int item) {  	layout.enableNonLoopAnim(item-1); -	int cash = getStarCoinCountShop(); +	int cash = getStarCoinCount();  	int cost;  	int Powerups[10]; diff --git a/src/koopatlas/starcoin.cpp b/src/koopatlas/starcoin.cpp index 54b7218..3842f87 100644 --- a/src/koopatlas/starcoin.cpp +++ b/src/koopatlas/starcoin.cpp @@ -1,26 +1,6 @@  #include "koopatlas/starcoin.h"  #include <game.h> -int getStarCoinCountCoins() { -	SaveBlock *save = GetSaveFile()->GetBlock(-1); -	int coinsSpent = save->credits_hiscore; -	int coinsEarned = 0; - -	for (int w = 0; w < 10; w++) { -		for (int l = 0; l < 10; l++) { -			u32 conds = save->GetLevelCondition(w, l); - -			if (conds & COND_COIN1) { coinsEarned++; } -			if (conds & COND_COIN2) { coinsEarned++; } -			if (conds & COND_COIN3) { coinsEarned++; } -		} -	} - -	int coinsLeft = coinsEarned - coinsSpent; -	return coinsLeft; -} - -  /*****************************************************************************/  // Starcoin Layout  // @@ -227,7 +207,7 @@ void dWMStarCoin::LoadCoinsForWorld(int world) {  	// Display Total Star Coin Count -	int myCoins = getStarCoinCountCoins(); +	int myCoins = getStarCoinCount();  	char myCoinsStr [4];  	sprintf(myCoinsStr, "%03d", myCoins); @@ -346,10 +326,10 @@ void dWMStarCoin::setText(const char *str, const char *name) {  	nw4r::ut::TextWriter tw;  	tw.font = box->font;  	tw.SetFontSize(box->fontSizeX, box->fontSizeY); -	tw.somethingRelatedToLineHeight = box->lineSpace; +	tw.lineSpace = box->lineSpace;  	tw.charSpace = box->charSpace;  	if (box->tagProc != 0) -		tw.tagProcessorMaybe = box->tagProc; +		tw.tagProcessor = box->tagProc;  	float width = tw.CalcStringWidth(newString, wlength);  	SpammyReport("Text width: %f\n", width); diff --git a/src/newer.cpp b/src/newer.cpp index 6d672e2..2bad8a0 100644 --- a/src/newer.cpp +++ b/src/newer.cpp @@ -1,4 +1,5 @@  #include <newer.h> +#include <game.h>  NWRWorld NewerWorldForLevelID(int w, int l) {  	switch (w) { @@ -75,3 +76,23 @@ const wchar_t *NewerWorldName(NWRWorld world) {  		return L"Unknown World";  	return NewerWorldNames[world];  } + + +int getStarCoinCount() { +	SaveBlock *save = GetSaveFile()->GetBlock(-1); +	int coinsSpent = save->credits_hiscore; +	int coinsEarned = 0; + +	for (int w = 0; w < 10; w++) { +		for (int l = 0; l < 10; l++) { +			u32 conds = save->GetLevelCondition(w, l); + +			if (conds & COND_COIN1) { coinsEarned++; } +			if (conds & COND_COIN2) { coinsEarned++; } +			if (conds & COND_COIN3) { coinsEarned++; } +		} +	} + +	int coinsLeft = coinsEarned - coinsSpent; +	return coinsLeft; +} diff --git a/src/palaceDude.cpp b/src/palaceDude.cpp index 6a8d7ff..8eb4a99 100644 --- a/src/palaceDude.cpp +++ b/src/palaceDude.cpp @@ -29,7 +29,7 @@ int dPalaceDude_c::onExecute() {  			dMsgBoxManager_c::instance->showMessage(settings & 0xFFFFFFF);  			SaveBlock *save = GetSaveFile()->GetBlock(-1); -			*((u8*)(((u32)GameMgr)+0x380)) |= (1 << (settings >> 28)); +			GameMgrP->switchPalaceFlag|= (1 << (settings >> 28));  		}  	} diff --git a/src/replay.S b/src/replay.S index 8c3f6c7..89868cf 100644 --- a/src/replay.S +++ b/src/replay.S @@ -27,7 +27,7 @@  .extern EGG__Heap__free__FPvPv  .extern GameHeap2  .extern EggControllerClassPtrMaybe -.extern GameMgr +.extern GameMgrP  .extern StrangeReplayValue1  .extern StrangeReplayValue2  .extern StrangeReplayValue3 @@ -192,8 +192,8 @@ replayStartLoop:  	lwzx r3, r3, r6  	stw r3, 0x18(r4) -	lis r3, GameMgr@h -	ori r3, r3, GameMgr@l +	lis r3, GameMgrP@h +	ori r3, r3, GameMgrP@l  	lwz r3, 0(r3)  	lbz r3, 0x380(r3)  	stb r3, 0x21(r4) diff --git a/src/switchblock.S b/src/switchblock.S index b86d5e2..4df2433 100644 --- a/src/switchblock.S +++ b/src/switchblock.S @@ -11,14 +11,14 @@  #endif  .align 4 -.extern GameMgr +.extern GameMgrP  .extern BG_GM_ptr  .extern _restgpr_27  .global BG_GM_InitRedSwitchFlag_Patch  BG_GM_InitRedSwitchFlag_Patch: -	lis r5, GameMgr@h -	ori r5, r5, GameMgr@l +	lis r5, GameMgrP@h +	ori r5, r5, GameMgrP@l  	lwz r5, 0(r5)  	addis r4, r3, 9  | 
