Re: Gruniożerca 3 - The Great Cavy Clean-Up!
Posted: Sat Feb 02, 2019 11:14 am
Got to level 12 or so. Very nice that you included solutions to everything.
NES Development Forums
https://forums.nesdev.org/
The great thing about this is that we also got "free" map solution reading(which would not be in game otherwise!)....so when Dzidzia is giving you a solution to the map, it reads back actual map data.Map starts with 8bit RAM offset for starting location.
The stream starts with a 2 "control" bits.
0-move with bits. Read bits to move in given direction. Next 3 bits for tile ID, more 5 bits is amount of moves.
1-small move with bits. 3 for tile and 3 for amount of moves
2-Sets Exit MT on player position. Proceeds to literal draw.
3-Carrot mode. EOR a carrot flag. This flag always starts as 0. Code fetches next control bits.
Once game finishes command 0 or 1, game will start asking for movement. Each move is 2 bits.
0-up
1-down
2-left
3-right
Once all move bits are processed, another 2 "control" bits will be given.
If code lands on tile 1F, it will replace it with currently selected MT.
If code lands on tile 0x1,0x2,0x4,0x5,0x7,0x8 it will be upgraded to higher level.
If Stair MT is selected, the MT id to be placed will include direction offset, allowing for some bit savings.
This will continue until amount of movement ends.
If Conveyor tile is selected, It makes a mini loop similiar to mode 0\1.
After amount of moves in given mode, game also expects 2 extra bits for direction in which place first Tile.
Later on the order of moving pointer and placing tile on map is reversed in the code.
The code still fetches directions as normal.
If Teleporter is selected, the amount of moves is not asked for. Instead a 8bit offset is asked.
After which, selected mode restarts.
if 8bit ofset is equal to 255, extra 4 bits will be asked.
These 4 bits will be interpreted as delay. 64 frames for single value.
These are for playing the solution and will indicate a number of frames to wait in between the moves.
This 255 offset will also *not* place a teleporter on the map.
Note: Carrot mode is turned off when control bits are fetched.
Note: Mixing 1, Explosive and Regen tiles is possible(no need to change type is tile was already placed)
Meaning, crossing regen tile while with 1 tile will upgrade regen instead of replacing.
;literal draw;
In this mode, game assumes you finished placing tiles normally.
All left are tiles that Grunio cant reach. Like ones destroyed by explosions.
Code intereprets bit stream in following manner:
6 bits - tile to place
3 bits - how many of them put on the map
8*repetition bits - map offset to put selected tile on.
Once all tiles of given id are placed, code rolls back to 6 bits for tile.
If tile ID is 0x3F, map loading is finished.
Some maps would ask too many Bytes to pathc in literal mode.
If tile ID is 0x3E, code shall ask for 8bit value for map offset and then jump to control code interpretation.
;Saving on bits;
Our MT table has 0x42 MTs. This means we need 7 bits to access all of them.
-To cut on this, we can limit our selection by MTs that are used for welldone screen.
Doing so saves us 1 bit.
-On entire 0x1X line is not required. If we create an ID list in ROM, with which we can reference
our true MT IDs,we can limit our selection to 0x1F MTs max.
Doing so saves us another 1 bit.
-If we use only 0x0F as exit, we are only 6 tiles shy of saving another bit.
If we make the code to actually upgrade tiles(when possible) instead of just placing them,
we can cut lv2 and lv3 versions of upgradeable tiles.
This allows us to place remaining 6 tiles in their place.
And so, another 1 bit was saved.
You could also remove Exit and Start points, but it has no benefit....or does it?
The ROM table should look like this:
0x01,0x04,0x07 ;These are upgradeable. Normal, Explosion and Regen
0x00,0x28,0x29 ;Stool, Start point and Carrot box
0x24,0x25,0x26,0x27 ;Stairs. Up down left right
0x0a,0x0b,0x0c,0x0d ;conveyors. up down left right
0x0e,0x0f ;teleporter and exit
-Now, we have 16 Tiles to choose from. At first, cutting down to 7 seems impossible but let us try...
We can remove Start tile(0x28) for free since its placed only at start of the level.
We can also remove (0x0F) tile as it is placed only once at end of the map.
This cuts us to 14 tiles...which doesnt saves us a 1 bit yet.
-By observing Stair tiles, we can notice that they always have to be placed in same direction to where player is moving.
If we make a control MT for Stairs instead of having all 4, we can offset correct MT by using the movement direction.
That shaves off 3 MT from our table....and shortens map bit stream a little.
-Same logic as above can be applied to Conveyor belts(with small exception, see above).
That saves another 3 MT from table.
With that, our table can be 8 MTs long, and thus can be adressed with 3 bits only.
The ROM table looks like this:
0x01,0x04,0x07 ;Its important to have upgradeables first, to make code bit easier and faster.
0x00,0x29 ;cant be upgraded, are not "special" cases.
0x24,0x0a ;special numbers for Stairs and Conveyors
0x0e ;teleporter
This saved a good chunk of ROM too.0x1F End of stream
0x1E Newline
0x1D Swap symbol table
0x1C Pull a word from dictionary
Up to 64 words. Pulls next 6bits from bitstream as ID of the word in dictionary.