BNJEdit - Bump & Jump Level Editor
Written by Michael Hayes
linktr.ee/intylab
Date Of Last Modification: October 18, 2021
__________

"What is this?"

This is a graphical application written in Python using Tkinter.  It
allows you to create a copy of the Intellivision Bump & Jump ROM image
with a custom set of 32 levels.
__________

What is included:

* New in the latest version

      readme.txt - what you are reading now
      bnjedit.py - the program itself
       config.py - a configuration file that you can tweak
      jzintv.exe - an Intellivision emulator to test your custom levels
     bin2rom.exe - utility to generate a ROM image
     rom2bin.exe - utility to convert your existing ROM image if needed
     bnjedit.bat - the script to launch BNJEdit
        temp.bat - a script that is automatically generated / executed
    hackfile.cfg - a keyboard hackfile that I use with jzIntv
  intycolors.cfg - an alternate Intellivision color scheme
    dbscript.txt - a script to automate the jzIntv debugger if enabled
*   musicfix.txt - an "include file" to implement the Music Fix feature
*consolidate.txt - another "include file"
*       icon.png - program icon
         assets/ - a subfolder containing all the graphics files
         images/ - the default subfolder that will contain your ROM
                   image.  This folder should already contain the file
                   bnjhack.cfg, where your work is saved to.
__________

Revision History:

2021-Oct-18:
* Bugfixes regarding the checkboxes:
  * '<' is used as an "include" statement in the jzintv debugger.
    Turns out it can't be used in a .cfg file; it only works when input
    manually from the jzIntv debug prompt.
    * It also doesn't like quotation marks in the path name.
  * A copy-and-paste error led to the second checkbox being bound to
    the same internal variable as the first one (for "Music Fix").
  * There were a few mistakes in consolidate.txt that led to corrupted
    rooms.  Those have been fixed.
* In the Windows port, I modified the call to bin2rom to suppress
  output to the terminal window.  Windows seems to be very slow in
  blitting text.  That's why I also added the "-q" flag for jzintv.

2021-Oct-15:
* I added a program icon.
* When you add one of the "skinny rooms", their default length is set
  to their default length as defined in the cartridge ROM.
* Bugfixes in the behavior of the pop-up menu.
  * You can now click on any of the Level rooms, including the End
    Room, using either the left or right mouse button, to invoke the
    menu options on that room.
  * (Code still exists to prevent deleting the End Room, of course.)
* You can now quit without being forced to agree to save your work.
* There's another checkbox, below "Music Fix".
  * It's designed to consolidate blank space in the original ROM by
    moving the Room and Level pointer tables to another ROm segment,
    and also move the room data.
  * Right now, it has no observable effect, but since I deciphered the
    room data, I'm making more space available to add new rooms for a
    future release.
* I created two new "reference" files, one for each of the two checkbox
  options.
* The huge text string in the config.py file that checks the "Music
  Fix" checkbox by default is replaced with a string to include the one
  new reference file.
  * Similarly, there's n additional line in config.py for
    "defaultconsolidation" with a value to check the new checkbox by
    default.
* Within the program Instructions:
  * I swapped the second and third pages.
  * I changed the text in what is now the third page, to describe how
    to open the pop-up menu.
  * I inserted a new fourth page, to describe the checkboxes' purposes.
* Changes to this readme file, relevant to the program changes.
  * There are separate instructions for whether you're installing just
    the update, or the entire program.
  * An extra paragraph is in the FAQ section, since I did locate and
    decipher the room data and pointer table in the ROM.
__________

Setup (if you are updating from the original release):

If you are installing BNJEdit for the first time, see the instructions
in the next section.

Unzip "bnjedit-20211018.zip" to your "projects/bnjedit" folder.
Overwrite bnjedit.py, config.py, and readme.txt, if you are prompted to
do so.  Your existing savefile in "images/bnjhack.cfg" is not affected.
__________

Setup (new installation):

If you are already using PIDEjL, 
then all you should need to do is
make sure the package is unzipped in
"projects/", which will create a
subfolder called "bnjedit/".

If you are not already using PIDEjL, then follow these steps:

A. Install Python.
     I. Go to python.org and download the latest version.
        You need Python 3.7 or greater.
        IMPORTANT!  As soon as you begin installation, check the box at
        the bottom of the first window to add Python to your PATH.  The
        box is unchecked by default.
B. Create a folder in the root of C:\ called "projects".
C. Copy or move bnjedit.zip into "C:\projects" and unzip it from there.
   It will create a subfolder called "bnjedit/" and unzip everything
   into there.
D. You should have your own copy of the Intellivision Bump & Jump ROM
   image with the extension .bin, .itv, or .int.  These are all the
   same; they contain the game's raw binary data.  Copy only this file
   WITHOUT the accompanying .cfg file into "projects/bnjedit/images/".
     I. If your ROM image is in .rom format, then use jzIntv's rom2bin
        utility to create a .bin and .cfg file.  Delete the .cfg file
        and move the .bin file into the "images/" subfolder.
    II. The reason you don't want to overwrite the .cfg file in the
        "images/" subfolder is that BNJEdit reads this file at startup
        and generates internal lists based on the sequence of the lines
        in the "[macro]" section.  These lists are vital to BNJEdit
        while it is running.
E. Rename the copied ROM image file to "bnjhack.bin".  BNJEdit will use
   this file, along with bnjhack.cfg, to create "bnjhack.rom" for you.
__________

How to use:

Enter "C:\projects\bnjedit\bnjedit.bat" in the Run prompt.

A window will appear with a set of controls on the right, a "Rooms"
pane in the middle, and a "Level" pane on the left.  There are
scrollbars for the two panes, but at the onset, only the Rooms pane
will be larger than the window.

First, let's get familiar with the command buttons.  In case you're
wondering, I designed the color scheme to be somewhat consistent with
the box image.

A. If you click on the "Instructions" button, a series of seven pop-up
   windows will briefly tell you what to do.
B. The "Save" button is "greyed-out" until you make a change.  When you
   do click on it, your work will be saved to "images/bnjhack.cfg".
C. You can back up the bnjhack.cfg file to "bnjhack.cfg~" by clicking
   on the "Backup" button.  BNJEdit will close and reopen again.  Your
   work is automatically saved.
D. The "Make .rom" button briefly closes BNJEdit and creates the file
   bnjhack.rom in the "images/" subfolder, which you can then run on
   any emulator you like.  You will be given an opportunity to either
   save your work or cancel, if you have unsaved work.
E. With the "Play .rom" button, you can playtest your levels in jzIntv.
   This also temporarily closes BNJEdit while you play, and prompts you
   to save your work if need be.
F. The "About" button pops up a window with the program name, author's
   name, and Date Of Last Modification.
G. Finally, the "Quit" button closes BNJEdit.  Once again, you are
   prompted to save your work if necessary.

In the bottom right corner are a few more controls.

A. The "Music Fix" option adds additional lines to bnjhack.cfg if the
   box is checked.  This slightly tweaks the in-game music to be more
   consistent with the arcade version of Bump & Jump.
B. The "Move Pointer Tables" option will seem not to make any
   difference for now.
     I. It moves the game's Room and Level pointer tables to another
        ROM segment which has enough blank space where they can fit.
    II. It also modifies the game code to look in the new location for
        these tables, and also moves the room data, consolidating blank
        space to make room for additional rooms in a future release.
C. Below that is the Level selector.  When you change levels, you will
   notice a change in some of the rooms' colors.  This is consistent
   with the game.
D. Finally, you can see how many rooms are in use.  There is space in
   the ROM for 1,798 rooms.  In the beginning, there are 32 rooms
   already in use: the End Room for each level.
     I. Before you get too excited, bear in mind that's spread out
        among 32 levels.  That's an average of just over 56 rooms per
        level, including the End Room for each level.
    II. This is not to be confused with the additional rooms I am
        making available in a future release.  The ROM segment which
        contains the level data will still only have room for 1,798
        rooms.  Where I am making more room is to have more than 21
        rooms to choose from in the future.

Moving a little to the left, we have the Rooms pane.  This contains the
21 rooms defined in the ROM.

A. When you hover over a room image, it will highlight, so you can
   easily see which room you are selecting.
B. Click on that room to add it to the Level pane.

That brings us to the Level pane, which is taking up the left half of
the window and is off-white in color.

A. At the top is the End Room.
B. Just below that is the text "Insert below".  This is the Insertion
   Point.  When a new room is added, it appears just below this point.
C. Below that are any rooms that you added from the Rooms pane, with a
   few parameter controls.
     I. First, if you have not already done so, select a room from the
        Rooms pane and click on it.
    II. To the right of each room, barring the End Room, are:
        a. "N/R/!".  The slider next to it can be set to one of three
           positions.  From right to left, these are:
             i. "!": The Water Hazard warning sign appears when the
                player enters this room.
            ii. "R" (Restart point): The player starts from the last
                room marked as a Restart point after losing a life.
           iii. "N" (Neither): neither of the above.
        b. The duration counter.  The six "skinny" rooms, barring the
           one with a boulder in lieu of a left guard rail, use the
           duration count to determine their length, with a range of
           1-63.  The remaining rooms use this count to determine how
           many times to repeat that room, with a range of 0-63.
   III. If you click on any of the rooms, a pop-up window appears with
        options to either move the Insertion Point or delete that room.
        You cannot delete the End Room, but you can move the Insertion
        Point beneath it again.  Right-clicking on the rooms also
        generates the pop-up menu.

When you are satisfied with your work, click on the "Save" button, and
then test the level by clicking on the "Make .rom" button followed by
the "Play .rom" button.

If the level plays as you want it to, move on to the next level.  If
you want to take a break, I suggest you click on the "Backup" button
before clicking on the "Quit" button to end off.
__________

FAQ

"Will there be an option to change the actual rooms in the future?"

That's not a feature I'm considering.  I think there's enough room for
creative talent to design exciting new levels just with the existing
rooms as they are defined in the original game ROM.

UPDATE: I did locate and decipher the room data in the ROM.  To add
support for new rooms in the future, I added a "consolidate" feature
that shuffles some leftover space in the ROM, making space for some
extra rooms.  To create new rooms yourself still falls outside the
scope of this project though.  Maybe I'll create a separate program to
allow people to design rooms, and then take the best submissions and
add them to this project.

"Can't you display the full length of each room?"

I probably can, but I left that out for three reasons.

First, I would have to repeatedly allocate/deallocate memory for up to
63 instances of the same image, which would make the code even more
convoluted than it already is.  That's not to mention resizing the
current room, resizing the canvas, and moving everything below that
room, including the Insertion Point if necessary.

Second, BNJEdit would potentially require a huge amount of memory.
Finally, resizing the room to display it so many times is actually
visually worse than to have to look at the Duration counter.

"Why does this require Python 3.7 and above?"

Some of the techniques I'm using depend on Python 3 to begin with.  I
have no interest in maintaining compatibility with legacy versions of
Python.  As for 3.7, this is the first version of Python that maintains
ordered Dictionaries.  Although BNJEdit should work with its nested
Dictionary objects unordered, I make no such guarantee.

"I heard there was an Easter egg."

Sort of.  Try restoring the bundled backup file.
__________

License stuff

There is no license or warranty of any kind.  I offer this package as a
tool rather than a product.  You are free to do whatever you want with
this tool, keeping in mind that the Bump & Jump ROM image, overlay
image, box image, and instruction manual are all copyrighted material,
which is why: you must supply those files yourself, and you should not
distribute those files in a bundle with BNJEdit.

The standard precaution applies that use of this tool is at your own
risk.  As it is free, I release this tool for your use with the
understanding that neither I nor Midnight Blue International, LLC are
responsible for any detrimental effects to you or your device as a
result of its use, either direct or indirect.

Rather than ask for any monetary donation, I would like to see your
completed level packs.  Just send me your bnjhack.cfg file, which does
not contain any copyrighted material.  If I consider including your
level pack in a future compilation, I will reach out to you for your
consent first.
__________

EOF
