Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Level parser for Jetpack levels
package main
import (
"encoding/binary"
"flag"
"image"
"strings"
"github.com/peterhellberg/gfx"
)
func ReadJET(fn string) (JET, error) {
var jet JET
f, err := gfx.OpenFile(fn)
if err != nil {
return jet, err
}
defer f.Close()
return jet, binary.Read(f, binary.LittleEndian, &jet)
}
func main() {
var out string
flag.StringVar(&out, "out", "", "Output file")
flag.Parse()
if flag.NArg() != 1 {
gfx.Log("Usage: jetpack-level-parser LEVEL.JET")
return
}
jet, err := ReadJET(flag.Arg(0))
if err != nil {
gfx.Fatal(err)
}
enc := gfx.NewJSONEncoder(gfx.Stdout)
enc.Encode(jet)
if out != "" {
gfx.SavePNG(out, gfx.NewScaledImage(jet.Image(), 16))
gfx.Log("Saved: %q", out)
}
}
type Door struct {
Position
}
type Start struct {
Position
}
type Position struct {
X uint8
Y uint8
}
func (p Position) Point() image.Point {
return image.Pt(int(p.X)-1, int(p.Y)-1)
}
type EnemyType uint8
const (
NoEnemy EnemyType = iota
Trackbot
SteelBall
Spring
Missile
Spikes
Flitzer
Batbot
Homer
)
type Enemy struct {
EnemyType `json:"enemy_type"`
Position
}
type JET struct {
Map [26 * 16]uint8 `json:"map"`
Door Door `json:"door"`
Start Start `json:"start"`
Enemies [20]Enemy `json:"enemies"`
Text [26]uint8 `json:"text"`
}
func (jet JET) Image() image.Image {
dst := gfx.NewPaletted(26, 16, jetpackPalette)
dst.Pix = jet.Map[:]
d := jet.Door.Point()
r := gfx.IR(d.X, d.Y, d.X+2, d.Y+2)
gfx.DrawColor(dst, r, doorColor)
gfx.SetPoint(dst, jet.Start.Point(), jetmanColor)
return dst
}
func (jet JET) Description() string {
return strings.Trim(string(jet.Text[:]), " ")
}
var jetmanColor = gfx.ColorMagenta
var doorColor = gfx.ColorNRGBA(0x51, 0x30, 0x10, 0xFF)
// Jetpack Palette based on Jetpack0.lbm
//
// Names from: http://tasvideos.org/GameResources/DOS/Jetpack.html
//
var jetpackPalette = gfx.Palette{
// Section 1 Row 1
{0x25, 0x25, 0x25, 0xFF}, // Background
{0xE7, 0xE7, 0xE7, 0xFF}, // Ladder
{0xC0, 0xC0, 0xC3, 0xFF}, // Moving Ladder Up
{0x91, 0x91, 0x93, 0xFF}, // Moving Ladder Down
{0x00, 0xF6, 0x00, 0xFF}, //
{0x73, 0x73, 0x73, 0xFF}, //
{0xED, 0xB9, 0x2F, 0xFF}, // Teleporter Yellow
{0xC7, 0x00, 0xB3, 0xFF}, // Teleporter Purple
{0x00, 0xBA, 0x00, 0xFF}, // Teleporter Green
{0x15, 0x18, 0xFF, 0xFF}, // Button Blue
{0x00, 0x07, 0xCF, 0xFF}, // Button Blue Pressed
{0xE3, 0x00, 0x00, 0xFF}, // Button Red
{0xCF, 0x09, 0x09, 0xFF}, // Button Red Pressed
{0x25, 0xCB, 0xA1, 0xFF}, // Button Cyan
{0x1D, 0xA7, 0x81, 0xFF}, // Button Cyan Pressed
{0xD8, 0xD8, 0xD8, 0xFF}, // Double Tank of Fuel
{0xE7, 0xE7, 0xE7, 0xFF}, // Single Tank of Fuel
{0xC3, 0xC3, 0xC3, 0xFF}, // Energy Charger
{0x91, 0x91, 0x91, 0xFF}, // Energy Drain
{0xBF, 0xBF, 0xBF, 0xFF}, // Monster Stunner
// Section 1 Row 2
{0xD8, 0xCF, 0x00, 0xFF}, // Gold Coin
{0xD8, 0xCF, 0x00, 0xFF}, // Pile of Gold
{0xFF, 0xFB, 0x5D, 0xFF}, // Golden Vase
{0xEA, 0xE3, 0x20, 0xFF}, // Extra Life
{0x2E, 0x2E, 0x2E, 0xFF}, // Hidden Spear
{0x25, 0x25, 0x25, 0xFF}, // Space
{0x9A, 0x72, 0x49, 0xFF}, // Fence
{0xDF, 0xDF, 0xDF, 0xFF}, // Column
{0x7F, 0xC7, 0xDE, 0xFF}, // Panel
{0x00, 0xA8, 0x00, 0xFF}, // Jungle/Vines/Ivy
{0xBE, 0x00, 0x00, 0xFF}, // Light Red Bricks
{0xA4, 0x2C, 0x00, 0xFF}, // Dark Red Bricks
{0xBE, 0xBE, 0xBE, 0xFF}, // Stone
{0x03, 0x08, 0xDE, 0xFF}, // Floor Switch Blue
{0xC4, 0x10, 0x10, 0xFF}, // Floor Switch Red
{0x21, 0xBB, 0x92, 0xFF}, // Floor Switch Cyan
{0xDF, 0xDF, 0xDF, 0xFF}, // Stationary Spikes Top
{0xDF, 0xDF, 0xDF, 0xFF}, // Stationary Spikes Right
{0xDF, 0xDF, 0xDF, 0xFF}, // Stationary Spikes Bottom
{0xDF, 0xDF, 0xDF, 0xFF}, // Stationary Spikes Left
// Section 1 Row 3
{0xB7, 0x02, 0x02, 0xFF}, // Rounded Light Red Bricks 1
{0xB7, 0x02, 0x02, 0xFF}, // Rounded Light Red Bricks 2
{0xB7, 0x02, 0x02, 0xFF}, // Rounded Light Red Bricks 3
{0xB7, 0x02, 0x02, 0xFF}, // Rounded Light Red Bricks 4
{0xB7, 0x02, 0x02, 0xFF}, // Rounded Light Red Bricks 5
{0xB7, 0x02, 0x02, 0xFF}, // Rounded Light Red Bricks 6
{0xB7, 0x02, 0x02, 0xFF}, // Rounded Light Red Bricks 7
{0xB7, 0x02, 0x02, 0xFF}, // Rounded Light Red Bricks 8
{0xB7, 0x02, 0x02, 0xFF}, // Rounded Light Red Bricks 9
{0xB7, 0x02, 0x02, 0xFF}, // Rounded Light Red Bricks 10
{0x73, 0x2B, 0x00, 0xFF}, // Rounded Dark Red Bricks 1
{0x73, 0x2B, 0x00, 0xFF}, // Rounded Dark Red Bricks 2
{0x73, 0x2B, 0x00, 0xFF}, // Rounded Dark Red Bricks 3
{0x73, 0x2B, 0x00, 0xFF}, // Rounded Dark Red Bricks 4
{0x73, 0x2B, 0x00, 0xFF}, // Rounded Dark Red Bricks 5
{0x73, 0x2B, 0x00, 0xFF}, // Rounded Dark Red Bricks 6
{0x73, 0x2B, 0x00, 0xFF}, // Rounded Dark Red Bricks 7
{0x73, 0x2B, 0x00, 0xFF}, // Rounded Dark Red Bricks 8
{0x73, 0x2B, 0x00, 0xFF}, // Rounded Dark Red Bricks 9
{0x73, 0x2B, 0x00, 0xFF}, // Rounded Dark Red Bricks 10
// Section 1 Row 4
{0xC6, 0xC6, 0xC6, 0xFF}, // Rounded Stone 1
{0xC6, 0xC6, 0xC6, 0xFF}, // Rounded Stone 2
{0xC6, 0xC6, 0xC6, 0xFF}, // Rounded Stone 3
{0xC6, 0xC6, 0xC6, 0xFF}, // Rounded Stone 4
{0xC6, 0xC6, 0xC6, 0xFF}, // Rounded Stone 5
{0xC6, 0xC6, 0xC6, 0xFF}, // Rounded Stone 6
{0xC6, 0xC6, 0xC6, 0xFF}, // Rounded Stone 7
{0xC6, 0xC6, 0xC6, 0xFF}, // Rounded Stone 8
{0xC6, 0xC6, 0xC6, 0xFF}, // Rounded Stone 9
{0xC6, 0xC6, 0xC6, 0xFF}, // Rounded Stone 10
{0x8A, 0x66, 0x3E, 0xFF}, // Box/Crate
{0xE6, 0x00, 0xCD, 0xFF}, // Steel Barrier Purple
{0x63, 0xC8, 0xE8, 0xFF}, // Panel
{0xE3, 0xA3, 0x00, 0xFF}, // Golden Block
{0x00, 0x07, 0xC7, 0xFF}, // Barrier Blue
{0x00, 0x07, 0xC7, 0xFF}, // Barrier Blue Horizontal
{0xE3, 0x00, 0x00, 0xFF}, // Barrier Red
{0xE3, 0x00, 0x00, 0xFF}, // Barrier Red Horizontal
{0x00, 0xCB, 0xBE, 0xFF}, // Barrier Cyan
{0x00, 0xCB, 0xBE, 0xFF}, // Barrier Cyan Horizontal
// Section 1 Row 5
{0xAD, 0x00, 0x00, 0xFF}, // Reinforced Light Red Bricks 1
{0xAD, 0x00, 0x00, 0xFF}, // Reinforced Light Red Bricks 2
{0xAD, 0x00, 0x00, 0xFF}, // Reinforced Light Red Bricks 3
{0xAD, 0x00, 0x00, 0xFF}, // Reinforced Light Red Bricks 4
{0xAD, 0x00, 0x00, 0xFF}, // Reinforced Light Red Bricks 5
{0xAD, 0x00, 0x00, 0xFF}, // Reinforced Light Red Bricks 6
{0xAD, 0x00, 0x00, 0xFF}, // Reinforced Light Red Bricks 7
{0xAD, 0x00, 0x00, 0xFF}, // Reinforced Light Red Bricks 8
{0xAD, 0x00, 0x00, 0xFF}, // Reinforced Light Red Bricks 9
{0xAD, 0x00, 0x00, 0xFF}, // Reinforced Light Red Bricks 10
{0xAD, 0x00, 0x00, 0xFF}, // Reinforced Light Red Bricks 11
{0xAD, 0x00, 0x00, 0xFF}, // Reinforced Light Red Bricks 12
{0xAD, 0x00, 0x00, 0xFF}, // Reinforced Light Red Bricks 13
{0xAD, 0x00, 0x00, 0xFF}, // Reinforced Light Red Bricks 14
{0xAD, 0x00, 0x00, 0xFF}, // Icy Light Red Bricks
{0x92, 0x2D, 0x00, 0xFF}, // Icy Dark Red Bricks
{0xC7, 0xC7, 0xC7, 0xFF}, // Icy Stone
{0xAD, 0x00, 0x00, 0xFF}, // Sludgy Light Red Bricks
{0x83, 0x2C, 0x00, 0xFF}, // Sludgy Dark Red Bricks
{0xBE, 0xBE, 0xBE, 0xFF}, // Sludgy Stone
// Section 1 Row 6
{0x7D, 0x2B, 0x00, 0xFF}, // Reinforced Dark Red Bricks 1
{0x7D, 0x2B, 0x00, 0xFF}, // Reinforced Dark Red Bricks 2
{0x7D, 0x2B, 0x00, 0xFF}, // Reinforced Dark Red Bricks 3
{0x7D, 0x2B, 0x00, 0xFF}, // Reinforced Dark Red Bricks 4
{0x7D, 0x2B, 0x00, 0xFF}, // Reinforced Dark Red Bricks 5
{0x7D, 0x2B, 0x00, 0xFF}, // Reinforced Dark Red Bricks 6
{0x7D, 0x2B, 0x00, 0xFF}, // Reinforced Dark Red Bricks 7
{0x7D, 0x2B, 0x00, 0xFF}, // Reinforced Dark Red Bricks 8
{0x7D, 0x2B, 0x00, 0xFF}, // Reinforced Dark Red Bricks 9
{0x7D, 0x2B, 0x00, 0xFF}, // Reinforced Dark Red Bricks 10
{0x7D, 0x2B, 0x00, 0xFF}, // Reinforced Dark Red Bricks 11
{0x7D, 0x2B, 0x00, 0xFF}, // Reinforced Dark Red Bricks 12
{0x7D, 0x2B, 0x00, 0xFF}, // Reinforced Dark Red Bricks 13
{0x7D, 0x2B, 0x00, 0xFF}, // Reinforced Dark Red Bricks 14
{0xAD, 0x00, 0x00, 0xFF}, // Moving Platform Left Light Red Bricks
{0x92, 0x2D, 0x00, 0xFF}, // Moving Platform Left Dark Red Bricks
{0xC7, 0xC7, 0xC7, 0xFF}, // Moving Platform Left Stone
{0xAD, 0x00, 0x00, 0xFF}, // Moving Platform Right Light Red Bricks
{0x83, 0x2C, 0x00, 0xFF}, // Moving Platform Right Dark Red Bricks
{0xBE, 0xBE, 0xBE, 0xFF}, // Moving Platform Right Stone
// Section 2 Row 1
{}, //{, 0xFF}, //
{}, //{, 0xFF}, //
{}, //{, 0xFF}, //
{}, //{, 0xFF}, //
{}, //{, 0xFF}, //
{}, //{, 0xFF}, //
{}, //{, 0xFF}, //
{}, //{, 0xFF}, //
{}, //{, 0xFF}, //
{}, //{, 0xFF}, //
{}, //{, 0xFF}, //
{}, //{, 0xFF}, //
{}, //{, 0xFF}, //
{}, //{, 0xFF}, //
{}, //{, 0xFF}, //
{}, //{, 0xFF}, //
{}, //{, 0xFF}, //
{}, //{, 0xFF}, //
{}, //{, 0xFF}, //
{}, //{, 0xFF}, //
}
@peterhellberg

This comment has been minimized.

Copy link
Owner Author

peterhellberg commented Oct 16, 2019

The Cursed Temple

jetpack-level-the-cursed-temple-in-dosbox

Binary file format

$ hexdump -v -e '26/1 " %02X" "\n"' TEMPLE.JET
 0B 48 00 00 48 16 23 00 00 48 48 20 20 20 48 48 00 00 00 00 1A 1A 00 00 1B 00
 12 48 07 07 48 48 48 1D 00 00 48 4F 4F 4F 48 00 00 00 00 00 63 63 63 63 63 63
 12 48 48 48 48 1D 1D 1D 1D 00 12 12 12 12 12 00 00 00 00 25 3C 01 00 00 1B 00
 12 1B 24 24 1B 1D 1D 1D 00 12 00 12 12 12 00 12 00 00 00 18 3C 01 18 00 24 10
 12 24 00 00 24 1D 1D 00 00 12 00 00 12 00 00 12 00 00 1D 63 46 19 24 6A 26 6D
 1D 1D 00 00 1D 1D 63 1D 00 12 12 12 12 12 12 12 00 1D 1D 20 46 46 00 00 24 00
 63 1D 1D 1D 1D 63 3C 63 1D 1D 00 12 12 12 00 1D 1D 63 63 63 66 16 1D 16 1D 16
 09 4A 63 63 63 3C 3C 20 4A 1D 1D 12 12 12 1D 1D 4A 20 3C 3C 13 18 66 18 66 19
 20 20 20 20 32 32 32 32 3C 63 63 27 21 25 63 63 3C 3C 32 32 32 32 32 32 32 1F
 66 66 66 1D 1D 1D 1D 1D 4C 13 6A 4D 4D 4D 6D 00 19 00 04 19 19 19 19 19 04 0B
 19 19 19 19 19 18 00 00 4C 18 67 19 19 19 69 01 19 00 6E 4F 4F 4F 4F 4F 6E 4B
 19 4D 4B 4B 01 62 62 19 62 62 67 19 19 19 69 00 19 01 65 01 01 01 01 01 65 12
 01 26 26 26 19 19 19 19 19 19 1F 1D 19 18 69 04 19 00 65 19 19 19 19 19 65 12
 01 00 65 01 01 32 32 32 01 62 32 6A 19 6D 32 66 19 00 65 19 26 19 26 19 65 10
 62 01 65 01 00 00 00 00 18 00 00 23 17 23 00 00 00 01 65 00 65 14 65 14 65 14
 04 04 65 01 1F 1F 1F 1F 1F 1F 1F 1F 1F 1F 1F 1F 1F 01 65 07 65 08 65 06 65 18
 03 01 1A 01 02 12 08 02 08 08 07 0D 0F 02 0C 01 03 0C 01 05 0C 01 08 0C 01 02
 0D 01 03 0D 01 05 0D 01 08 0D 01 02 0E 01 03 0E 01 05 0E 01 08 0E 01 00 00 00
 00 00 00 00 00 00 00 00 00 00 00 00 54 48 45 20 43 55 52 53 45 44 20 20 20 54
 45 4D 50 4C 45 20 20 20 20 20 20 20

Output when drawing the tiles using the gfx.PaletteSplendor128 palette

jetpack-level-TEMPLE JET

@peterhellberg

This comment has been minimized.

Copy link
Owner Author

peterhellberg commented Oct 16, 2019

Play the Jetpack Christmas Special over at the Internet Archive

https://archive.org/details/msdos_Jetpack_Christmas_Special_1993

Or download the FREEWARE version of Jetpack

http://www.adeptsoftware.com/jetpack/

(The game works quite well in http://boxerapp.com)

@peterhellberg

This comment has been minimized.

@peterhellberg

This comment has been minimized.

Copy link
Owner Author

peterhellberg commented Oct 16, 2019

Work in Progress on a jetpack palette

package main

import (
	"encoding/binary"
	"flag"
	"image"
	"io"
	"strings"

	"github.com/peterhellberg/gfx"
)

func main() {
	var out string

	flag.StringVar(&out, "out", "/tmp/jetpack-level-parser.png", "Output file")

	flag.Parse()

	if flag.NArg() != 1 {
		gfx.Log("Usage: jetpack-level-parser LEVEL.JET")
		return
	}

	var jet JET

	gfx.ReadFile(flag.Arg(0), func(r io.Reader) error {
		return binary.Read(r, binary.LittleEndian, &jet)
	})

	gfx.Log("Map: %q %#v", jet, jet)

	gfx.SavePNG(out, gfx.NewScaledImage(jet.Image(), 16))

	gfx.Log("Saved: %q", out)
}

type JET struct {
	Map         [26 * 16]uint8
	DoorX       uint8
	DoorY       uint8
	PlayerX     uint8
	PlayerY     uint8
	Unknown     [60]uint8
	Description [25]uint8
}

func (jet JET) Image() image.Image {
	dst := gfx.NewPaletted(26, 16, jetpackPalette)

	dst.Pix = jet.Map[:]

	d := jet.Door()
	r := gfx.IR(d.X, d.Y, d.X+2, d.Y+2)
	gfx.Log("%#v", r)
	gfx.DrawColor(dst, r, doorColor)
	gfx.SetPoint(dst, jet.Player(), jetmanColor)

	return dst
}

func (jet JET) String() string {
	return strings.Trim(string(jet.Description[:]), " ")
}

func (jet JET) Player() image.Point {
	return image.Pt(int(jet.PlayerX)-1, int(jet.PlayerY)-1)
}

func (jet JET) Door() image.Point {
	return image.Pt(int(jet.DoorX)-1, int(jet.DoorY)-1)
}

var jetmanColor = gfx.ColorMagenta
var doorColor = gfx.ColorNRGBA(0x51, 0x30, 0x10, 0xFF)

// Jetpack Palette based on Jetpack0.lbm
//
// Names from: http://tasvideos.org/GameResources/DOS/Jetpack.html
//
var jetpackPalette = gfx.Palette{
	// Section 1 Row 1
	{0x25, 0x25, 0x25, 0xFF}, // Background
	{0xE7, 0xE7, 0xE7, 0xFF}, // Ladder
	{0xC0, 0xC0, 0xC3, 0xFF}, // Moving Ladder Up
	{0x91, 0x91, 0x93, 0xFF}, // Moving Ladder Down
	{0x00, 0xF6, 0x00, 0xFF}, //
	{0x73, 0x73, 0x73, 0xFF}, //
	{0xED, 0xB9, 0x2F, 0xFF}, // Teleporter Yellow
	{0xC7, 0x00, 0xB3, 0xFF}, // Teleporter Purple
	{0x00, 0xBA, 0x00, 0xFF}, // Teleporter Green
	{0x15, 0x18, 0xFF, 0xFF}, // Button Blue
	{0x00, 0x07, 0xCF, 0xFF}, // Button Blue Pressed
	{0xE3, 0x00, 0x00, 0xFF}, // Button Red
	{0xCF, 0x09, 0x09, 0xFF}, // Button Red Pressed
	{0x25, 0xCB, 0xA1, 0xFF}, // Button Cyan
	{0x1D, 0xA7, 0x81, 0xFF}, // Button Cyan Pressed
	{0xD8, 0xD8, 0xD8, 0xFF}, // Double Tank of Fuel
	{0xE7, 0xE7, 0xE7, 0xFF}, // Single Tank of Fuel
	{0xC3, 0xC3, 0xC3, 0xFF}, // Energy Charger
	{0x91, 0x91, 0x91, 0xFF}, // Energy Drain
	{0xBF, 0xBF, 0xBF, 0xFF}, // Monster Stunner

	// Section 1 Row 2
	{0xD8, 0xCF, 0x00, 0xFF}, // Gold Coin
	{0xD8, 0xCF, 0x00, 0xFF}, // Pile of Gold
	{0xFF, 0xFB, 0x5D, 0xFF}, // Golden Vase
	{0xEA, 0xE3, 0x20, 0xFF}, // Extra Life
	{0x2E, 0x2E, 0x2E, 0xFF}, // Hidden Spear
	{0x25, 0x25, 0x25, 0xFF}, // Space
	{0x9A, 0x72, 0x49, 0xFF}, // Fence
	{0xDF, 0xDF, 0xDF, 0xFF}, // Column
	{0x7F, 0xC7, 0xDE, 0xFF}, // Panel
	{0x00, 0xA8, 0x00, 0xFF}, // Jungle/Vines/Ivy
	{0xBE, 0x00, 0x00, 0xFF}, // Light Red Bricks
	{0xA4, 0x2C, 0x00, 0xFF}, // Dark Red Bricks
	{0xBE, 0xBE, 0xBE, 0xFF}, // Stone
	{0x03, 0x08, 0xDE, 0xFF}, // Floor Switch Blue
	{0xC4, 0x10, 0x10, 0xFF}, // Floor Switch Red
	{0x21, 0xBB, 0x92, 0xFF}, // Floor Switch Cyan
	{0xDF, 0xDF, 0xDF, 0xFF}, // Stationary Spikes Top
	{0xDF, 0xDF, 0xDF, 0xFF}, // Stationary Spikes Right
	{0xDF, 0xDF, 0xDF, 0xFF}, // Stationary Spikes Bottom
	{0xDF, 0xDF, 0xDF, 0xFF}, // Stationary Spikes Left

	// Section 1 Row 3
	{0xB7, 0x02, 0x02, 0xFF}, // Rounded Light Red Bricks 1
	{0xB7, 0x02, 0x02, 0xFF}, // Rounded Light Red Bricks 2
	{0xB7, 0x02, 0x02, 0xFF}, // Rounded Light Red Bricks 3
	{0xB7, 0x02, 0x02, 0xFF}, // Rounded Light Red Bricks 4
	{0xB7, 0x02, 0x02, 0xFF}, // Rounded Light Red Bricks 5
	{0xB7, 0x02, 0x02, 0xFF}, // Rounded Light Red Bricks 6
	{0xB7, 0x02, 0x02, 0xFF}, // Rounded Light Red Bricks 7
	{0xB7, 0x02, 0x02, 0xFF}, // Rounded Light Red Bricks 8
	{0xB7, 0x02, 0x02, 0xFF}, // Rounded Light Red Bricks 9
	{0xB7, 0x02, 0x02, 0xFF}, // Rounded Light Red Bricks 10
	{0x73, 0x2B, 0x00, 0xFF}, // Rounded Dark Red Bricks 1
	{0x73, 0x2B, 0x00, 0xFF}, // Rounded Dark Red Bricks 2
	{0x73, 0x2B, 0x00, 0xFF}, // Rounded Dark Red Bricks 3
	{0x73, 0x2B, 0x00, 0xFF}, // Rounded Dark Red Bricks 4
	{0x73, 0x2B, 0x00, 0xFF}, // Rounded Dark Red Bricks 5
	{0x73, 0x2B, 0x00, 0xFF}, // Rounded Dark Red Bricks 6
	{0x73, 0x2B, 0x00, 0xFF}, // Rounded Dark Red Bricks 7
	{0x73, 0x2B, 0x00, 0xFF}, // Rounded Dark Red Bricks 8
	{0x73, 0x2B, 0x00, 0xFF}, // Rounded Dark Red Bricks 9
	{0x73, 0x2B, 0x00, 0xFF}, // Rounded Dark Red Bricks 10

	// Section 1 Row 4
	{0xC6, 0xC6, 0xC6, 0xFF}, // Rounded Stone 1
	{0xC6, 0xC6, 0xC6, 0xFF}, // Rounded Stone 2
	{0xC6, 0xC6, 0xC6, 0xFF}, // Rounded Stone 3
	{0xC6, 0xC6, 0xC6, 0xFF}, // Rounded Stone 4
	{0xC6, 0xC6, 0xC6, 0xFF}, // Rounded Stone 5
	{0xC6, 0xC6, 0xC6, 0xFF}, // Rounded Stone 6
	{0xC6, 0xC6, 0xC6, 0xFF}, // Rounded Stone 7
	{0xC6, 0xC6, 0xC6, 0xFF}, // Rounded Stone 8
	{0xC6, 0xC6, 0xC6, 0xFF}, // Rounded Stone 9
	{0xC6, 0xC6, 0xC6, 0xFF}, // Rounded Stone 10
	{0x8A, 0x66, 0x3E, 0xFF}, // Box/Crate
	{0xE6, 0x00, 0xCD, 0xFF}, // Steel Barrier Purple
	{0x63, 0xC8, 0xE8, 0xFF}, // Panel
	{0xE3, 0xA3, 0x00, 0xFF}, // Golden Block
	{0x00, 0x07, 0xC7, 0xFF}, // Barrier Blue
	{0x00, 0x07, 0xC7, 0xFF}, // Barrier Blue Horizontal
	{0xE3, 0x00, 0x00, 0xFF}, // Barrier Red
	{0xE3, 0x00, 0x00, 0xFF}, // Barrier Red Horizontal
	{0x00, 0xCB, 0xBE, 0xFF}, // Barrier Cyan
	{0x00, 0xCB, 0xBE, 0xFF}, // Barrier Cyan Horizontal

	// Section 1 Row 5
	{0xAD, 0x00, 0x00, 0xFF}, // Reinforced Light Red Bricks 1
	{0xAD, 0x00, 0x00, 0xFF}, // Reinforced Light Red Bricks 2
	{0xAD, 0x00, 0x00, 0xFF}, // Reinforced Light Red Bricks 3
	{0xAD, 0x00, 0x00, 0xFF}, // Reinforced Light Red Bricks 4
	{0xAD, 0x00, 0x00, 0xFF}, // Reinforced Light Red Bricks 5
	{0xAD, 0x00, 0x00, 0xFF}, // Reinforced Light Red Bricks 6
	{0xAD, 0x00, 0x00, 0xFF}, // Reinforced Light Red Bricks 7
	{0xAD, 0x00, 0x00, 0xFF}, // Reinforced Light Red Bricks 8
	{0xAD, 0x00, 0x00, 0xFF}, // Reinforced Light Red Bricks 9
	{0xAD, 0x00, 0x00, 0xFF}, // Reinforced Light Red Bricks 10
	{0xAD, 0x00, 0x00, 0xFF}, // Reinforced Light Red Bricks 11
	{0xAD, 0x00, 0x00, 0xFF}, // Reinforced Light Red Bricks 12
	{0xAD, 0x00, 0x00, 0xFF}, // Reinforced Light Red Bricks 13
	{0xAD, 0x00, 0x00, 0xFF}, // Reinforced Light Red Bricks 14
	{0xAD, 0x00, 0x00, 0xFF}, // Icy Light Red Bricks
	{0x92, 0x2D, 0x00, 0xFF}, // Icy Dark Red Bricks
	{0xC7, 0xC7, 0xC7, 0xFF}, // Icy Stone
	{0xAD, 0x00, 0x00, 0xFF}, // Sludgy Light Red Bricks
	{0x83, 0x2C, 0x00, 0xFF}, // Sludgy Dark Red Bricks
	{0xBE, 0xBE, 0xBE, 0xFF}, // Sludgy Stone

	// Section 1 Row 6
	{0x7D, 0x2B, 0x00, 0xFF}, // Reinforced Dark Red Bricks 1
	{0x7D, 0x2B, 0x00, 0xFF}, // Reinforced Dark Red Bricks 2
	{0x7D, 0x2B, 0x00, 0xFF}, // Reinforced Dark Red Bricks 3
	{0x7D, 0x2B, 0x00, 0xFF}, // Reinforced Dark Red Bricks 4
	{0x7D, 0x2B, 0x00, 0xFF}, // Reinforced Dark Red Bricks 5
	{0x7D, 0x2B, 0x00, 0xFF}, // Reinforced Dark Red Bricks 6
	{0x7D, 0x2B, 0x00, 0xFF}, // Reinforced Dark Red Bricks 7
	{0x7D, 0x2B, 0x00, 0xFF}, // Reinforced Dark Red Bricks 8
	{0x7D, 0x2B, 0x00, 0xFF}, // Reinforced Dark Red Bricks 9
	{0x7D, 0x2B, 0x00, 0xFF}, // Reinforced Dark Red Bricks 10
	{0x7D, 0x2B, 0x00, 0xFF}, // Reinforced Dark Red Bricks 11
	{0x7D, 0x2B, 0x00, 0xFF}, // Reinforced Dark Red Bricks 12
	{0x7D, 0x2B, 0x00, 0xFF}, // Reinforced Dark Red Bricks 13
	{0x7D, 0x2B, 0x00, 0xFF}, // Reinforced Dark Red Bricks 14
	{0xAD, 0x00, 0x00, 0xFF}, // Moving Platform Left Light Red Bricks
	{0x92, 0x2D, 0x00, 0xFF}, // Moving Platform Left Dark Red Bricks
	{0xC7, 0xC7, 0xC7, 0xFF}, // Moving Platform Left Stone
	{0xAD, 0x00, 0x00, 0xFF}, // Moving Platform Right Light Red Bricks
	{0x83, 0x2C, 0x00, 0xFF}, // Moving Platform Right Dark Red Bricks
	{0xBE, 0xBE, 0xBE, 0xFF}, // Moving Platform Right Stone

	// Section 2 Row 1
	{}, //{, 0xFF}, //
	{}, //{, 0xFF}, //
	{}, //{, 0xFF}, //
	{}, //{, 0xFF}, //
	{}, //{, 0xFF}, //
	{}, //{, 0xFF}, //
	{}, //{, 0xFF}, //
	{}, //{, 0xFF}, //
	{}, //{, 0xFF}, //
	{}, //{, 0xFF}, //
	{}, //{, 0xFF}, //
	{}, //{, 0xFF}, //
	{}, //{, 0xFF}, //
	{}, //{, 0xFF}, //
	{}, //{, 0xFF}, //
	{}, //{, 0xFF}, //
	{}, //{, 0xFF}, //
	{}, //{, 0xFF}, //
	{}, //{, 0xFF}, //
	{}, //{, 0xFF}, //

	// Section 3 Row 1
	gfx.ColorMagenta,
	gfx.ColorMagenta,
	gfx.ColorMagenta,
	gfx.ColorMagenta,
	gfx.ColorMagenta,
	gfx.ColorMagenta,
	gfx.ColorMagenta,
	gfx.ColorMagenta,
	gfx.ColorMagenta,
	gfx.ColorMagenta,
	gfx.ColorMagenta,
	gfx.ColorMagenta,
	gfx.ColorMagenta,
	gfx.ColorMagenta,
	gfx.ColorMagenta,
	gfx.ColorMagenta,
	gfx.ColorMagenta,
	gfx.ColorMagenta,
	gfx.ColorMagenta,
	gfx.ColorMagenta,
	gfx.ColorMagenta,
	gfx.ColorMagenta,
	gfx.ColorMagenta,
	gfx.ColorMagenta,
}

TEMPLE

Goldx01
Goldx03
Goldx05
Goldx06
Goldx07
Goldx08
Goldx09

@peterhellberg

This comment has been minimized.

Copy link
Owner Author

peterhellberg commented Oct 16, 2019

@peterhellberg

This comment has been minimized.

Copy link
Owner Author

peterhellberg commented Oct 17, 2019

package main

import (
	"encoding/binary"
	"flag"
	"image"
	"strings"

	"github.com/peterhellberg/gfx"
)

func ReadJET(fn string) (JET, error) {
	var jet JET

	f, err := gfx.OpenFile(fn)
	if err != nil {
		return JET{}, err
	}
	defer f.Close()

	return jet, binary.Read(f, binary.LittleEndian, &jet)
}

func main() {
	enc := gfx.NewJSONEncoder(gfx.Stdout, gfx.JSONIndent("", "  "))

	var out string

	flag.StringVar(&out, "out", "", "Output file")

	flag.Parse()

	if flag.NArg() != 1 {
		gfx.Log("Usage: jetpack-level-parser LEVEL.JET")
		return
	}

	jet, err := ReadJET(flag.Arg(0))
	if err != nil {
		gfx.Fatal(err)
	}

	enc.Encode(jet)

	if out != "" {
		gfx.SavePNG(out, gfx.NewScaledImage(jet.Image(), 16))

		gfx.Log("Saved: %q", out)
	}
}

type Door struct {
	Position
}

type Start struct {
	Position
}

type Position struct {
	X uint8
	Y uint8
}

func (p Position) Point() image.Point {
	return image.Pt(int(p.X)-1, int(p.Y)-1)
}

type EnemyType uint8

const (
	NoEnemy EnemyType = iota
	Trackbot
	SteelBall
	Spring
	Missile
	Spikes
	Flitzer
	Batbot
	Homer
)

type Enemy struct {
	EnemyType `json:"enemy_type"`
	Position
}

type JET struct {
	Map     [26 * 16]uint8 `json:"map"`
	Door    Door           `json:"door"`
	Start   Start          `json:"start"`
	Enemies [20]Enemy      `json:"enemies"`
	Text    [26]uint8      `json:"text"`
}

func (jet JET) Image() image.Image {
	dst := gfx.NewPaletted(26, 16, jetpackPalette)

	dst.Pix = jet.Map[:]

	d := jet.Door.Point()
	r := gfx.IR(d.X, d.Y, d.X+2, d.Y+2)

	gfx.DrawColor(dst, r, doorColor)
	gfx.SetPoint(dst, jet.Start.Point(), jetmanColor)

	return dst
}

func (jet JET) Description() string {
	return strings.Trim(string(jet.Text[:]), " ")
}

var jetmanColor = gfx.ColorMagenta
var doorColor = gfx.ColorNRGBA(0x51, 0x30, 0x10, 0xFF)

// Jetpack Palette based on Jetpack0.lbm
//
// Names from: http://tasvideos.org/GameResources/DOS/Jetpack.html
//
var jetpackPalette = gfx.Palette{
	// Section 1 Row 1
	{0x25, 0x25, 0x25, 0xFF}, // Background
	{0xE7, 0xE7, 0xE7, 0xFF}, // Ladder
	{0xC0, 0xC0, 0xC3, 0xFF}, // Moving Ladder Up
	{0x91, 0x91, 0x93, 0xFF}, // Moving Ladder Down
	{0x00, 0xF6, 0x00, 0xFF}, //
	{0x73, 0x73, 0x73, 0xFF}, //
	{0xED, 0xB9, 0x2F, 0xFF}, // Teleporter Yellow
	{0xC7, 0x00, 0xB3, 0xFF}, // Teleporter Purple
	{0x00, 0xBA, 0x00, 0xFF}, // Teleporter Green
	{0x15, 0x18, 0xFF, 0xFF}, // Button Blue
	{0x00, 0x07, 0xCF, 0xFF}, // Button Blue Pressed
	{0xE3, 0x00, 0x00, 0xFF}, // Button Red
	{0xCF, 0x09, 0x09, 0xFF}, // Button Red Pressed
	{0x25, 0xCB, 0xA1, 0xFF}, // Button Cyan
	{0x1D, 0xA7, 0x81, 0xFF}, // Button Cyan Pressed
	{0xD8, 0xD8, 0xD8, 0xFF}, // Double Tank of Fuel
	{0xE7, 0xE7, 0xE7, 0xFF}, // Single Tank of Fuel
	{0xC3, 0xC3, 0xC3, 0xFF}, // Energy Charger
	{0x91, 0x91, 0x91, 0xFF}, // Energy Drain
	{0xBF, 0xBF, 0xBF, 0xFF}, // Monster Stunner

	// Section 1 Row 2
	{0xD8, 0xCF, 0x00, 0xFF}, // Gold Coin
	{0xD8, 0xCF, 0x00, 0xFF}, // Pile of Gold
	{0xFF, 0xFB, 0x5D, 0xFF}, // Golden Vase
	{0xEA, 0xE3, 0x20, 0xFF}, // Extra Life
	{0x2E, 0x2E, 0x2E, 0xFF}, // Hidden Spear
	{0x25, 0x25, 0x25, 0xFF}, // Space
	{0x9A, 0x72, 0x49, 0xFF}, // Fence
	{0xDF, 0xDF, 0xDF, 0xFF}, // Column
	{0x7F, 0xC7, 0xDE, 0xFF}, // Panel
	{0x00, 0xA8, 0x00, 0xFF}, // Jungle/Vines/Ivy
	{0xBE, 0x00, 0x00, 0xFF}, // Light Red Bricks
	{0xA4, 0x2C, 0x00, 0xFF}, // Dark Red Bricks
	{0xBE, 0xBE, 0xBE, 0xFF}, // Stone
	{0x03, 0x08, 0xDE, 0xFF}, // Floor Switch Blue
	{0xC4, 0x10, 0x10, 0xFF}, // Floor Switch Red
	{0x21, 0xBB, 0x92, 0xFF}, // Floor Switch Cyan
	{0xDF, 0xDF, 0xDF, 0xFF}, // Stationary Spikes Top
	{0xDF, 0xDF, 0xDF, 0xFF}, // Stationary Spikes Right
	{0xDF, 0xDF, 0xDF, 0xFF}, // Stationary Spikes Bottom
	{0xDF, 0xDF, 0xDF, 0xFF}, // Stationary Spikes Left

	// Section 1 Row 3
	{0xB7, 0x02, 0x02, 0xFF}, // Rounded Light Red Bricks 1
	{0xB7, 0x02, 0x02, 0xFF}, // Rounded Light Red Bricks 2
	{0xB7, 0x02, 0x02, 0xFF}, // Rounded Light Red Bricks 3
	{0xB7, 0x02, 0x02, 0xFF}, // Rounded Light Red Bricks 4
	{0xB7, 0x02, 0x02, 0xFF}, // Rounded Light Red Bricks 5
	{0xB7, 0x02, 0x02, 0xFF}, // Rounded Light Red Bricks 6
	{0xB7, 0x02, 0x02, 0xFF}, // Rounded Light Red Bricks 7
	{0xB7, 0x02, 0x02, 0xFF}, // Rounded Light Red Bricks 8
	{0xB7, 0x02, 0x02, 0xFF}, // Rounded Light Red Bricks 9
	{0xB7, 0x02, 0x02, 0xFF}, // Rounded Light Red Bricks 10
	{0x73, 0x2B, 0x00, 0xFF}, // Rounded Dark Red Bricks 1
	{0x73, 0x2B, 0x00, 0xFF}, // Rounded Dark Red Bricks 2
	{0x73, 0x2B, 0x00, 0xFF}, // Rounded Dark Red Bricks 3
	{0x73, 0x2B, 0x00, 0xFF}, // Rounded Dark Red Bricks 4
	{0x73, 0x2B, 0x00, 0xFF}, // Rounded Dark Red Bricks 5
	{0x73, 0x2B, 0x00, 0xFF}, // Rounded Dark Red Bricks 6
	{0x73, 0x2B, 0x00, 0xFF}, // Rounded Dark Red Bricks 7
	{0x73, 0x2B, 0x00, 0xFF}, // Rounded Dark Red Bricks 8
	{0x73, 0x2B, 0x00, 0xFF}, // Rounded Dark Red Bricks 9
	{0x73, 0x2B, 0x00, 0xFF}, // Rounded Dark Red Bricks 10

	// Section 1 Row 4
	{0xC6, 0xC6, 0xC6, 0xFF}, // Rounded Stone 1
	{0xC6, 0xC6, 0xC6, 0xFF}, // Rounded Stone 2
	{0xC6, 0xC6, 0xC6, 0xFF}, // Rounded Stone 3
	{0xC6, 0xC6, 0xC6, 0xFF}, // Rounded Stone 4
	{0xC6, 0xC6, 0xC6, 0xFF}, // Rounded Stone 5
	{0xC6, 0xC6, 0xC6, 0xFF}, // Rounded Stone 6
	{0xC6, 0xC6, 0xC6, 0xFF}, // Rounded Stone 7
	{0xC6, 0xC6, 0xC6, 0xFF}, // Rounded Stone 8
	{0xC6, 0xC6, 0xC6, 0xFF}, // Rounded Stone 9
	{0xC6, 0xC6, 0xC6, 0xFF}, // Rounded Stone 10
	{0x8A, 0x66, 0x3E, 0xFF}, // Box/Crate
	{0xE6, 0x00, 0xCD, 0xFF}, // Steel Barrier Purple
	{0x63, 0xC8, 0xE8, 0xFF}, // Panel
	{0xE3, 0xA3, 0x00, 0xFF}, // Golden Block
	{0x00, 0x07, 0xC7, 0xFF}, // Barrier Blue
	{0x00, 0x07, 0xC7, 0xFF}, // Barrier Blue Horizontal
	{0xE3, 0x00, 0x00, 0xFF}, // Barrier Red
	{0xE3, 0x00, 0x00, 0xFF}, // Barrier Red Horizontal
	{0x00, 0xCB, 0xBE, 0xFF}, // Barrier Cyan
	{0x00, 0xCB, 0xBE, 0xFF}, // Barrier Cyan Horizontal

	// Section 1 Row 5
	{0xAD, 0x00, 0x00, 0xFF}, // Reinforced Light Red Bricks 1
	{0xAD, 0x00, 0x00, 0xFF}, // Reinforced Light Red Bricks 2
	{0xAD, 0x00, 0x00, 0xFF}, // Reinforced Light Red Bricks 3
	{0xAD, 0x00, 0x00, 0xFF}, // Reinforced Light Red Bricks 4
	{0xAD, 0x00, 0x00, 0xFF}, // Reinforced Light Red Bricks 5
	{0xAD, 0x00, 0x00, 0xFF}, // Reinforced Light Red Bricks 6
	{0xAD, 0x00, 0x00, 0xFF}, // Reinforced Light Red Bricks 7
	{0xAD, 0x00, 0x00, 0xFF}, // Reinforced Light Red Bricks 8
	{0xAD, 0x00, 0x00, 0xFF}, // Reinforced Light Red Bricks 9
	{0xAD, 0x00, 0x00, 0xFF}, // Reinforced Light Red Bricks 10
	{0xAD, 0x00, 0x00, 0xFF}, // Reinforced Light Red Bricks 11
	{0xAD, 0x00, 0x00, 0xFF}, // Reinforced Light Red Bricks 12
	{0xAD, 0x00, 0x00, 0xFF}, // Reinforced Light Red Bricks 13
	{0xAD, 0x00, 0x00, 0xFF}, // Reinforced Light Red Bricks 14
	{0xAD, 0x00, 0x00, 0xFF}, // Icy Light Red Bricks
	{0x92, 0x2D, 0x00, 0xFF}, // Icy Dark Red Bricks
	{0xC7, 0xC7, 0xC7, 0xFF}, // Icy Stone
	{0xAD, 0x00, 0x00, 0xFF}, // Sludgy Light Red Bricks
	{0x83, 0x2C, 0x00, 0xFF}, // Sludgy Dark Red Bricks
	{0xBE, 0xBE, 0xBE, 0xFF}, // Sludgy Stone

	// Section 1 Row 6
	{0x7D, 0x2B, 0x00, 0xFF}, // Reinforced Dark Red Bricks 1
	{0x7D, 0x2B, 0x00, 0xFF}, // Reinforced Dark Red Bricks 2
	{0x7D, 0x2B, 0x00, 0xFF}, // Reinforced Dark Red Bricks 3
	{0x7D, 0x2B, 0x00, 0xFF}, // Reinforced Dark Red Bricks 4
	{0x7D, 0x2B, 0x00, 0xFF}, // Reinforced Dark Red Bricks 5
	{0x7D, 0x2B, 0x00, 0xFF}, // Reinforced Dark Red Bricks 6
	{0x7D, 0x2B, 0x00, 0xFF}, // Reinforced Dark Red Bricks 7
	{0x7D, 0x2B, 0x00, 0xFF}, // Reinforced Dark Red Bricks 8
	{0x7D, 0x2B, 0x00, 0xFF}, // Reinforced Dark Red Bricks 9
	{0x7D, 0x2B, 0x00, 0xFF}, // Reinforced Dark Red Bricks 10
	{0x7D, 0x2B, 0x00, 0xFF}, // Reinforced Dark Red Bricks 11
	{0x7D, 0x2B, 0x00, 0xFF}, // Reinforced Dark Red Bricks 12
	{0x7D, 0x2B, 0x00, 0xFF}, // Reinforced Dark Red Bricks 13
	{0x7D, 0x2B, 0x00, 0xFF}, // Reinforced Dark Red Bricks 14
	{0xAD, 0x00, 0x00, 0xFF}, // Moving Platform Left Light Red Bricks
	{0x92, 0x2D, 0x00, 0xFF}, // Moving Platform Left Dark Red Bricks
	{0xC7, 0xC7, 0xC7, 0xFF}, // Moving Platform Left Stone
	{0xAD, 0x00, 0x00, 0xFF}, // Moving Platform Right Light Red Bricks
	{0x83, 0x2C, 0x00, 0xFF}, // Moving Platform Right Dark Red Bricks
	{0xBE, 0xBE, 0xBE, 0xFF}, // Moving Platform Right Stone

	// Section 2 Row 1
	{}, //{, 0xFF}, //
	{}, //{, 0xFF}, //
	{}, //{, 0xFF}, //
	{}, //{, 0xFF}, //
	{}, //{, 0xFF}, //
	{}, //{, 0xFF}, //
	{}, //{, 0xFF}, //
	{}, //{, 0xFF}, //
	{}, //{, 0xFF}, //
	{}, //{, 0xFF}, //
	{}, //{, 0xFF}, //
	{}, //{, 0xFF}, //
	{}, //{, 0xFF}, //
	{}, //{, 0xFF}, //
	{}, //{, 0xFF}, //
	{}, //{, 0xFF}, //
	{}, //{, 0xFF}, //
	{}, //{, 0xFF}, //
	{}, //{, 0xFF}, //
	{}, //{, 0xFF}, //
}
go run jetpack-level-parser.go "/Users/peter/DOS Games/Jetpak.boxer/C.harddisk/jetpak15/LEVELS/TEMPLE.JET"
{
  "map": [
    11,
    72,
    0,
    0,
    72,
    22,
    35,
    0,
    0,
    72,
    72,
    32,
    32,
    32,
    72,
    72,
    0,
    0,
    0,
    0,
    26,
    26,
    0,
    0,
    27,
    0,
    18,
    72,
    7,
    7,
    72,
    72,
    72,
    29,
    0,
    0,
    72,
    79,
    79,
    79,
    72,
    0,
    0,
    0,
    0,
    0,
    99,
    99,
    99,
    99,
    99,
    99,
    18,
    72,
    72,
    72,
    72,
    29,
    29,
    29,
    29,
    0,
    18,
    18,
    18,
    18,
    18,
    0,
    0,
    0,
    0,
    37,
    60,
    1,
    0,
    0,
    27,
    0,
    18,
    27,
    36,
    36,
    27,
    29,
    29,
    29,
    0,
    18,
    0,
    18,
    18,
    18,
    0,
    18,
    0,
    0,
    0,
    24,
    60,
    1,
    24,
    0,
    36,
    16,
    18,
    36,
    0,
    0,
    36,
    29,
    29,
    0,
    0,
    18,
    0,
    0,
    18,
    0,
    0,
    18,
    0,
    0,
    29,
    99,
    70,
    25,
    36,
    106,
    38,
    109,
    29,
    29,
    0,
    0,
    29,
    29,
    99,
    29,
    0,
    18,
    18,
    18,
    18,
    18,
    18,
    18,
    0,
    29,
    29,
    32,
    70,
    70,
    0,
    0,
    36,
    0,
    99,
    29,
    29,
    29,
    29,
    99,
    60,
    99,
    29,
    29,
    0,
    18,
    18,
    18,
    0,
    29,
    29,
    99,
    99,
    99,
    102,
    22,
    29,
    22,
    29,
    22,
    9,
    74,
    99,
    99,
    99,
    60,
    60,
    32,
    74,
    29,
    29,
    18,
    18,
    18,
    29,
    29,
    74,
    32,
    60,
    60,
    19,
    24,
    102,
    24,
    102,
    25,
    32,
    32,
    32,
    32,
    50,
    50,
    50,
    50,
    60,
    99,
    99,
    39,
    33,
    37,
    99,
    99,
    60,
    60,
    50,
    50,
    50,
    50,
    50,
    50,
    50,
    31,
    102,
    102,
    102,
    29,
    29,
    29,
    29,
    29,
    76,
    19,
    106,
    77,
    77,
    77,
    109,
    0,
    25,
    0,
    4,
    25,
    25,
    25,
    25,
    25,
    4,
    11,
    25,
    25,
    25,
    25,
    25,
    24,
    0,
    0,
    76,
    24,
    103,
    25,
    25,
    25,
    105,
    1,
    25,
    0,
    110,
    79,
    79,
    79,
    79,
    79,
    110,
    75,
    25,
    77,
    75,
    75,
    1,
    98,
    98,
    25,
    98,
    98,
    103,
    25,
    25,
    25,
    105,
    0,
    25,
    1,
    101,
    1,
    1,
    1,
    1,
    1,
    101,
    18,
    1,
    38,
    38,
    38,
    25,
    25,
    25,
    25,
    25,
    25,
    31,
    29,
    25,
    24,
    105,
    4,
    25,
    0,
    101,
    25,
    25,
    25,
    25,
    25,
    101,
    18,
    1,
    0,
    101,
    1,
    1,
    50,
    50,
    50,
    1,
    98,
    50,
    106,
    25,
    109,
    50,
    102,
    25,
    0,
    101,
    25,
    38,
    25,
    38,
    25,
    101,
    16,
    98,
    1,
    101,
    1,
    0,
    0,
    0,
    0,
    24,
    0,
    0,
    35,
    23,
    35,
    0,
    0,
    0,
    1,
    101,
    0,
    101,
    20,
    101,
    20,
    101,
    20,
    4,
    4,
    101,
    1,
    31,
    31,
    31,
    31,
    31,
    31,
    31,
    31,
    31,
    31,
    31,
    31,
    31,
    1,
    101,
    7,
    101,
    8,
    101,
    6,
    101,
    24
  ],
  "door": {
    "X": 3,
    "Y": 1
  },
  "start": {
    "X": 26,
    "Y": 1
  },
  "enemies": [
    {
      "enemy_type": 2,
      "X": 18,
      "Y": 8
    },
    {
      "enemy_type": 2,
      "X": 8,
      "Y": 8
    },
    {
      "enemy_type": 7,
      "X": 13,
      "Y": 15
    },
    {
      "enemy_type": 2,
      "X": 12,
      "Y": 1
    },
    {
      "enemy_type": 3,
      "X": 12,
      "Y": 1
    },
    {
      "enemy_type": 5,
      "X": 12,
      "Y": 1
    },
    {
      "enemy_type": 8,
      "X": 12,
      "Y": 1
    },
    {
      "enemy_type": 2,
      "X": 13,
      "Y": 1
    },
    {
      "enemy_type": 3,
      "X": 13,
      "Y": 1
    },
    {
      "enemy_type": 5,
      "X": 13,
      "Y": 1
    },
    {
      "enemy_type": 8,
      "X": 13,
      "Y": 1
    },
    {
      "enemy_type": 2,
      "X": 14,
      "Y": 1
    },
    {
      "enemy_type": 3,
      "X": 14,
      "Y": 1
    },
    {
      "enemy_type": 5,
      "X": 14,
      "Y": 1
    },
    {
      "enemy_type": 8,
      "X": 14,
      "Y": 1
    },
    {
      "enemy_type": 0,
      "X": 0,
      "Y": 0
    },
    {
      "enemy_type": 0,
      "X": 0,
      "Y": 0
    },
    {
      "enemy_type": 0,
      "X": 0,
      "Y": 0
    },
    {
      "enemy_type": 0,
      "X": 0,
      "Y": 0
    },
    {
      "enemy_type": 0,
      "X": 0,
      "Y": 0
    }
  ],
  "text": [
    84,
    72,
    69,
    32,
    67,
    85,
    82,
    83,
    69,
    68,
    32,
    32,
    32,
    84,
    69,
    77,
    80,
    76,
    69,
    32,
    32,
    32,
    32,
    32,
    32,
    32
  ]
}
@peterhellberg

This comment has been minimized.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.