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.