How some unlocks are made - zhuowei/MinecraftPEModWiki GitHub Wiki
##Smooth Lighting##
First, force Minecraft PE to branch to the Smooth Lighting section of TileRenderer::tesselateBlockInWorld.
000f31cc <TileRenderer::tesselateBlockInWorld(Tile*, int, int, int)>:
@snip
f31f4: 447b add r3, pc
f31f6: 681b ldr r3, [r3, #0]
f31f8: 781b ldrb r3, [r3, #0] @load r3 from preferences
@snip
f322e: b96b cbnz r3, f324c <TileRenderer::tesselateBlockInWorld(Tile*, int, int, int)+0x80>
@branch to smooth lighting if r3 is not zero
@snip
f324c: 4643 mov r3, r8
f324e: f8cd 9000 str.w r9, [sp]
f3252: edcd 6a01 vstr s13, [sp, #4]
f3256: ed8d 7a02 vstr s14, [sp, #8]
f325a: edcd 7a03 vstr s15, [sp, #12]
f325e: f7fe fc2f bl f1ac0 <TileRenderer::tesselateBlockInWorldWithAmbienceOcclusion(Tile*, int, int, int, float, float, float)>
@ambience occlusion is the name MrMessiah gave to his smooth lighting mod.
@It got included in Desktop edition, and got ported to Pocket Edition.
@History lesson :)
f3262: e7f0 b.n f3246 <TileRenderer::tesselateBlockInWorld(Tile*, int, int, int)+0x7a>
So, of course, to force it to branch, change that ldrb r3, [r3, #0] to a movs r3, #1 instruction: replace it with 0123.
That gets us a Minecraft PE that creates weird triangular shadows. That's because Minecraft PE renders in GL_FLAT shading mode. We, of course, could just remove all calls to set to that mode.
Look for sections like this:
c27d4: f44f 50e8 mov.w r0, #7424 ; 0x1d00
c27d8: f7ed e97a blx afad0 <AppPlatform::~AppPlatform()-0x33f8>
Remove all the blx instructions after #7424 (GL_FLAT) by replacing them with 00bf (nop).
Test, generate patch, and you're done.
##Elemental Explosions## There's only one Level::setTile call in Explosion::finalizeExplosions.
0012e098 <Explosion::finalizeExplosion()>:
@snip
12e192: 4650 mov r0, sl
12e194: 4641 mov r1, r8
12e196: 464a mov r2, r9
12e198: 4633 mov r3, r6
12e19a: 2700 movs r7, #0 @air
12e19c: 9700 str r7, [sp, #0] @store onto stack so that it becomes argument 4
12e19e: f001 fd87 bl 12fcb0 <Level::setTileNoUpdate(int, int, int, int)>
The last parameter is pushed onto the stack, so the mov instruction before it loads the block ID. Change the 0027 to something else - 0a27 would give you lava, for example.
Test, generate patch; you're done.
##Caves patch## There's an actual cave generator in Minecraft PE, but I cannot figure out how to unlock it. :(
Don't worry! There's something that resembles caves in Minecraft PE already: underground gravel and dirt. Those are generated in the chunk provider (RandomLevelSource, called ChunkProviderGenerate by MCP and Bukkit) with OreFeature (called WorldGenMinable in my ancient Bukkit mc-dev Desktop Edition decompile). The relevant code from the desktop edition as of Beta 1.2_01 is:
for (k1 = 0; k1 < 20; ++k1) {
l1 = k + this.j.nextInt(16);
i2 = this.j.nextInt(128);
j2 = l + this.j.nextInt(16);
(new WorldGenMinable(Block.DIRT.id, 32)).a(this.p, this.j, l1, i2, j2);
}
As you can see, the first call to WorldGenMinable in the generator goes to the populator for dirt. The same snippet of code in PE 0.4.0:
13cb76: 2614 movs r6, #20
@I think that this sets the number of times the code is called - like the desktop edition, it's 20
13cb78: 58fb ldr r3, [r7, r3]
13cb7a: f8dd 9020 ldr.w r9, [sp, #32]
13cb7e: f8dd 8024 ldr.w r8, [sp, #36] ; 0x24
13cb82: 930b str r3, [sp, #44] ; 0x2c
13cb84: f8df 363c ldr.w r3, [pc, #1596] ; 13d1c4 <RandomLevelSource::postProcess(ChunkSource*, int, int)+0x7e4>
13cb88: f857 a003 ldr.w sl, [r7, r3]
13cb8c: 9f0b ldr r7, [sp, #44] ; 0x2c
13cb8e: f8cd 901c str.w r9, [sp, #28]
13cb92: 3708 adds r7, #8
13cb94: f8cd 8020 str.w r8, [sp, #32]
13cb98: 9709 str r7, [sp, #36] ; 0x24
13cb9a: 4620 mov r0, r4
13cb9c: f788 ffc0 bl c5b20 <Random::genrand_int32()>
13cba0: f8dd e01c ldr.w lr, [sp, #28]
13cba4: 4680 mov r8, r0
13cba6: 4620 mov r0, r4
13cba8: f008 080f and.w r8, r8, #15
13cbac: 44f0 add r8, lr
13cbae: f788 ffb7 bl c5b20 <Random::genrand_int32()>
13cbb2: 4681 mov r9, r0
13cbb4: 4620 mov r0, r4
13cbb6: f788 ffb3 bl c5b20 <Random::genrand_int32()>
13cbba: f8da 3000 ldr.w r3, [sl]
13cbbe: 9a08 ldr r2, [sp, #32]
13cbc0: 2100 movs r1, #0
13cbc2: f009 097f and.w r9, r9, #127 ; 0x7f
13cbc6: 689f ldr r7, [r3, #8]
@ we know from before that #8 is where the block ID on a Tile object is stored
13cbc8: f000 0b0f and.w fp, r0, #15
13cbcc: a814 add r0, sp, #80 ; 0x50
13cbce: 4493 add fp, r2
13cbd0: f002 fcc0 bl 13f554 <Feature::Feature(bool)>
13cbd4: f8d5 e000 ldr.w lr, [r5]
13cbd8: a814 add r0, sp, #80 ; 0x50
13cbda: 9909 ldr r1, [sp, #36] ; 0x24
13cbdc: 4622 mov r2, r4
13cbde: 4643 mov r3, r8
13cbe0: 9716 str r7, [sp, #88] ; 0x58
13cbe2: e88d 0a00 stmia.w sp, {r9, fp}
13cbe6: 2720 movs r7, #32
@ this part stores "32" in new OreFeature(Block.dirt.id, 32)
13cbe8: 9114 str r1, [sp, #80] ; 0x50
13cbea: 4671 mov r1, lr
13cbec: 9717 str r7, [sp, #92] ; 0x5c
@ this part stores the block ID that we got above into #92 on the feature
13cbee: f7ff fbaf bl 13c350 <OreFeature::place(Level*, Random*, int, int, int)>
13cbf2: 9f0a ldr r7, [sp, #40] ; 0x28
13cbf4: 3e01 subs r6, #1
So to make caves, we'll need to change that block ID to 0 (air), and we'll need to make lots of it. I doubled the 20 to 40 ending up with 28 26 (movs r6, #40) instead of 14 26 (movs r6, #20), and changed the ldr r7, [r3, #8] which loaded the block ID to a movs r7, #0 (00 27), which, of course, loads 0 as the block ID.
I also made a lite version that does not increase the number of times the game tries to generate caves from 20.