Ditto's code: Code Ditto

Hello, have some coding I’ve done.

For every hack I have just include “Installer.event” as per usual somewhere in your buildfile. If you use FEBuilder just select “Installer.event” from the Insert EA menu. Customise whatever you want to, I’m not your mother.

Things I have made:

Battle BGM Customiser (from original post)

Download: - GitHub

FEBuilder Patch Download: Battle BGM Customiser - GitHub

I’ve updated this to be properly fully functional. It takes over the default battle BGM playing function, and allows everything to be edited from an EA Installer.

This includes:

  • Battle Music per faction per chapter, set in chapter data at offsets +0x1C, +0x1E and +0x20.

  • Sieglinde/Siegmund weapon specific BGM can be set per weapon and by more than 2 weapons.

  • Which characters that ignore the Sieglinde/Siegmund BGM is now customisable, too.

  • Staff BGM is customisable per staff.

  • Dancer, Bard, Promotion and Arena BGMs are able to be set (this is nothing new, however).

  • Continuous Map ↔ Battle BGM, by setting the chapter battle BGM to 0xFFFF or the same as the phase’s map BGM.

This engine hack does all of these things that were possible using other engine hacks, but since this takes over EkrPlayMainBGM, I needed to have all of them in one.


more fresh hacks coming soon to a this thread store near you image

26 Likes

This looks awesome! Hopefully it can be added as an FEBuilder patch with a menu for editing weapons and units. That would be the cherry on top.

1 Like

I’ve actually been adding some more features due to this overwriting the main battle BGM function (also you can’t use songs > 0xFF due to it being a byte not a short but that’s a whole other can of worms), once that’s all sorted if I can find documentation on how to make the actual .txt for builder to recognise and also setup some gui, I will be making a builder patch most likely.

3 Likes

genuine question: what are the actual modules here that make this modular? this just looks like a single hardcoding customization

1 Like

I wrote the title at 3am and was really tired, my mistake, will change.
I do know this isn’t modular, it’s just an EA installer with tables which isn’t exactly very modular at all. My bad.
Thanks for bringing this to my attention though, I definitely would not have remembered to change it otherwise.

1 Like

I’ve updated the title post, it now contains the proper details for the complete version of my BGM editing escapades’ work.

Might start working on an FEBuilder patch to make this more accessible to FEBuilder users!

Hope some people get use out of this!

2 Likes

interested FEBuilder user here.

2 Likes

My ineptitude once again brings me to fixing this code again

However this time, I’ve got continuous Map <—> Battle BGM working now by setting the Battle BGM to 0xFFFF or having the Map BGM and Battle BGM be the same value. This applies to staves as well.

1 Like

Making patches for FEBuilder is a pain, but I’ve done one now, for BattleBGMCustomiser.

First post contains a link to a folder with the patches, download the folder and add it to the patch folder for FEBuilder to install it and edit from there.

Everything is able to be edited from there, and keep in mind this code comes with defaults for vanilla FE8.

I will probably try and make FEBuilder patches for anything else I release, as this isn’t actually that bad.

6 Likes

thanks dittoomfie

1 Like

Amazing stuff! Will try it out later. Looks very promising

1 Like

Buildfile Split PTABLE

I’m posting this here just so any buildfiler who wants to have a split PTABLE won’t have to go through the hassle of doing it themselves.

Do note you’ll need to make sure your MAKE_HACK is reading map files with the correct (new) macros in them; you’ll need to edit tmx2ea.py or add an external script to edit the output of tmx2ea.exe immediately after they’ve been made.

This contains macros for each table in this split, and already has the vanilla tileset objects, palettes, configs and tile anims in the tables.

Thanks to AuraWolf for giving me the last fix (the ASM code) needed for this.

The .event itself:
/*
First Empty entry:
Config - 0xB
Object/Palette - 0x24
Tile Anim 1 - 0x6
Tile Anim 2 - 0x2
Map Data - 0x1
Tile Changes - 0x1
Events - 0x1

Pointers:
0x19900 - Tile Config
0x19968 - OBJ
0x1999C - PAL
0x30134 - Tile Anim 1 \
0x30C78 - Tile Anim 2 -\ Use Same Table
0x34680 - Map Data
0x346AC - Tile Changes
0x346DC - Events
*/

#define SetTilesetConfig(entry, pointer) "PUSH; ORG Config_PTABLE + (entry*4); POIN pointer; POP"
PUSH; ORG 0x19900; POIN Config_PTABLE; POP
ALIGN 4; Config_PTABLE:
FILL 257*4
SetTilesetConfig(0x1, 0x1AB96C) //Fields
SetTilesetConfig(0x2, 0x1AA140) //Village
SetTilesetConfig(0x3, 0x1A8CCC) //Castle
SetTilesetConfig(0x4, 0x1A7674) //Plains
SetTilesetConfig(0x5, 0x1A6604) //Fort
SetTilesetConfig(0x6, 0x1A55B4) //Desert
SetTilesetConfig(0x7, 0x1A3660) //Black Temple
SetTilesetConfig(0x8, 0x1A1FC0) //Mountainous
SetTilesetConfig(0x9, 0x1A0514) //Temple
SetTilesetConfig(0xA, 0x1A1440) //Stronghold

#define SetTilesetObject(entry, pointer) "PUSH; ORG Object_PTABLE + (entry*4); POIN pointer; POP"

//Code from AuraWolf - fixes bug where map palette is weird after opening unit menu
PUSH
ORG 0x1990C //Inline edit (yipee my rom space is saved by an insignificant amount!)
WORD $1C04B570 $F01A4D0E $1C06FE81 $807930 $490C5828 $FB16F7F9 $807970 $28005828 $4909D002 $FB0EF7F9 $8079B0 $58084907 $5222A0 $F7E721C0 $BC70FA39 $4700BC01
POIN Object_PTABLE
WORD $6008000 $600C000
POIN Palette_PTABLE
POP

ALIGN 4; Object_PTABLE:
FILL 257*4
SetTilesetObject(0x1, 0x1ADCF0) //Fields
SetTilesetObject(0x2, 0x191B14) //Village
SetTilesetObject(0x3, 0x18B89C) //Castle
SetTilesetObject(0x4, 0x185154) //Plains
SetTilesetObject(0x5, 0x17A9F4) //Desert
SetTilesetObject(0x6, 0x1756B4) //Lava Cave
SetTilesetObject(0x7, 0x170DA8) //Black Temple
SetTilesetObject(0x8, 0x169D54) //Mountainous
SetTilesetObject(0x9, 0x1609BC) //Temple
SetTilesetObject(0xA, 0x165F7C) //Stronghold

#define SetTilesetPalette(entry, pointer) "PUSH; ORG Palette_PTABLE + (entry*4); POIN pointer; POP"
PUSH; ORG 0x1999C; POIN Palette_PTABLE; POP
ALIGN 4; Palette_PTABLE:
FILL 257*4

SetTilesetPalette(0x1, 0x1AEBF0) //Fields Pal 1
SetTilesetPalette(0x2, 0x1AE5B0) //Fields Pal 2
SetTilesetPalette(0x3, 0x1AE0B0) //Fields Pal 3
SetTilesetPalette(0x4, 0x1ADCF0) //Fields Pal 4

SetTilesetPalette(0x5, 0x1AEAB0) //Village Pal 1
SetTilesetPalette(0x6, 0x1AD7F0) //Village Pal 2
SetTilesetPalette(0x7, 0x1ACF30) //Village Pal 3

SetTilesetPalette(0x8, 0x1AE970) //Castle Pal 1
SetTilesetPalette(0x9, 0x1AE1F0) //Castle Pal 2
SetTilesetPalette(0xA, 0x1ADE30) //Castle Pal 3
SetTilesetPalette(0xB, 0x1AD2F0) //Castle Pal 4

SetTilesetPalette(0xC, 0x1AE830) //Plains Pal 1
SetTilesetPalette(0xD, 0x1AE6F0) //Plains Pal 2

SetTilesetPalette(0xE, 0x1A3470) //Fort Pal 1
SetTilesetPalette(0xF, 0x1ADA70) //Fort Pal 2
SetTilesetPalette(0x10, 0x1AD1B0) //Fort Pal 3

SetTilesetPalette(0x11, 0x1AE330) //Desert

SetTilesetPalette(0x12, 0x1ADF70) //Lava Cave

SetTilesetPalette(0x13, 0x1ADBB0) //Black Temple

SetTilesetPalette(0x14, 0x1AD930) //Mountainous Pal 1
SetTilesetPalette(0x15, 0x1AD430) //Mountainous Pal 2

SetTilesetPalette(0x16, 0x1AD570) //Temple

SetTilesetPalette(0x17, 0x1AD6B0) //Stronghold Pal 1
SetTilesetPalette(0x18, 0x1AD070) //Stronghold Pal 2

#define SetTileAnim(entry, pointer) "PUSH; ORG TileAnim_PTABLE + (entry*4); POIN pointer; POP"
PUSH; ORG 0x30134; POIN TileAnim_PTABLE; ORG 0x30C78; POIN TileAnim_PTABLE; POP
ALIGN 4; TileAnim_PTABLE:
FILL 257*4

SetTileAnim(0x1, 0x59D498) //Plains Water TileAnim1
SetTileAnim(0x2, 0x59D568) //Village Water TileAnim1
SetTileAnim(0x3, 0x59D6F8) //Castle Water TileAnim1
SetTileAnim(0x4, 0x59D678) //Stronghold Torch TileAnim1
SetTileAnim(0x5, 0x59D520) //Boat Map Water TileAnim1

SetTileAnim(0x6, 0x59D800) //Lava Cave TileAnim2

#define SetMapData(entry, pointer) "PUSH; ORG MapData_PTABLE + (entry*4); POIN pointer; POP"
PUSH; ORG 0x34680; POIN MapData_PTABLE; POP
ALIGN 4; MapData_PTABLE:
FILL 257*4

#define SetTileChanges(entry, pointer) "PUSH; ORG TileChanges_PTABLE + (entry*4); POIN pointer; POP"
PUSH; ORG 0x346AC; POIN TileChanges_PTABLE; POP
ALIGN 4; TileChanges_PTABLE:
FILL 257*4

#define SetChapterEvents(entry, pointer) "PUSH; ORG ChapterEvents_PTABLE + (entry*4); POIN pointer; POP"
PUSH; ORG 0x346DC; POIN ChapterEvents_PTABLE; POP
ALIGN 4; ChapterEvents_PTABLE:
FILL 257*4
The ASM source for the inline edit:
.thumb

.global LoadChapterMapGfx
.type LoadChapterMapGfx, %function

.equ origin, 0x0801990C

.equ Decompress_6008000, 0x06008000
.equ Decompress_600C000, 0x0600C000

.equ bl_GetChapterDefinition, . + 0x08034618 - origin
.equ bl_Decompress, . + 0x08012F50 - origin
.equ bl_CopyToPaletteBuffer, . + 0x08000DB8 - origin


		LoadChapterMapGfx:
		push	{r4-r6,r14}
		mov		r4, r0
		
		@Check map object type
		ldr		r5, =Object_PTABLE
		bl		bl_GetChapterDefinition
		mov		r6, r0
		ldrb	r0, [r6,#4]
		lsl		r0, #2
		ldr		r0, [r5,r0]
		ldr		r1, =Decompress_6008000
		bl		bl_Decompress
		
		@I'm not sure what this is for (or what table it should load with split ptable)
		ldrb	r0, [r6,#5]
		lsl		r0, #2
		ldr		r0, [r5,r0]
		cmp		r0, #0
		beq		GetMapPalette
		
			ldr		r1, =Decompress_600C000
			bl		bl_Decompress
			
		GetMapPalette:
		ldrb	r0, [r6,#6]
		lsl		r0, #2
		ldr		r1, =Palette_PTABLE
		ldr		r0, [r1,r0]
		mov		r2, #0xA0
		lsl		r2, #1
		mov		r1, #0xC0
		bl		bl_CopyToPaletteBuffer
		
		pop		{r4-r6}
		pop		{r0}
		bx		r0
		
		.align
		.ltorg
4 Likes

gee i sure do wonder what hack currently has this specific code in it

1 Like

I’m sorry. But I don’t quite understand what this does??? What is a split PTABLE? What function does it serve?

Map and tileset stuff, might also have chapter events and terrain changes, but I forget. Splits them up so you can add more and things.

Your code is awesome Ditto

1 Like

Remove Game Over BGM from the proc

When a game over occurs, the proc script responsible for calling all of the functions in a game over also calls a function to play a song, in it’s case 0x3E.

This rewrites the proc to no longer play any music, which is useful if you have eventing before a game over and you want the music to stay the same.

Download: GameOverMusicFix.event

4 Likes

Set Unit Status rewrite

Download: Set Unit Stats
Installation is as simple as #includeing the .lyn.event.

Does what it says on the tin, includes 2 event ASMCs:

SetUnitStats sets byte (in s1) of the desired unit’s (charID in s2, takes special inputs like (-1)) struct to a value (in s3).

GetUnitStats gets byte (in s1) of the desired unit’s (charID in s2, takes special inputs like (-1)) struct and returns it in sC.

Did this because I couldn’t be bothered trying to mangle 7743’s SetUnitStatus into my buildfile. Works for builder as well if any of those users are displeased with the weird restrictions on SetUnitStatus.

7 Likes

If you want a more comprehensive version of SetUnitStatus, it was the first thing I released on my asm thread years ago. Your version always sets one byte at a time and is great if you don’t want to be overwhelmed by a large number of definitions and options.

https://github.com/Veslyquix/Pokemblem/tree/master/Patches/ASMCs/SetStatus
There are also various febuilder asmcs in my project that you might find useful.

2 Likes

No Rain or Snow Move Costs

A short inline change I think is rather useful.

Applying this will disregard rain and snow move cost pointers entirely, so they will never be used. And this means you never have to change them to all be the same pointer if you’re normal and don’t want bad movement! Hurrah!

Oh and, when I said short, I meant one line of EA script:

PUSH; ORG 0x18D5A; SHORT 0xD014; POP
1 Like