Jump to content
IGNORED

Indenture


edyensid

Recommended Posts

Is anyone out there still playing with Indenture? I recently started playing it again, using DosBox on XP, so I could finish my maps I started making about 9 or so years ago. :)

I made my maps after seeing the cool map graphic of the original game that Warren Robinett had on his website, made by Maurice Molyneaux. Then there was someone else (dont remember the name) around 2002 timeframe that made the Indenture Mapping Project and dumproom program, that would dump all the rooms for v1.5 into a text file. This site also had some GIF files of some large areas mapped out. Anyways, these made me want to map it out as well, so I thank them for that! I also made a little VB app that can read the v1.5 and v1.7 .COM files and show a graphical view of the rooms and their connecting rooms.

 

Anyway, if anyone is still a fan of this awesome Adventure remake by Craig Pell, I would be more than happy to share my maps and talk about this old classic. For some reason I still love this game and just cannot get it out of my head.

 

Ed

Link to comment
Share on other sites

Some screens, particularly the swiss cheese mazes, would be a real challenge to do faithfully. You'd have to use a kernel capable of asymmetrical display. And even then there might be a few stumbling blocks. As such, Adventure's original kernel (and the modified one I did) are inadequate.

Link to comment
Share on other sites

Some screens, particularly the swiss cheese mazes, would be a real challenge to do faithfully. You'd have to use a kernel capable of asymmetrical display. And even then there might be a few stumbling blocks. As such, Adventure's original kernel (and the modified one I did) are inadequate.

How about the new kernel you made for Earthquake? He was doing some amazing stuff with that one. Wouldn't it still be too many rooms though? I thought it was limited to 256 rooms and if I remember right Indenture has about 300 rooms.

Edited by accousticguitar
Link to comment
Share on other sites

It would be nice to have a version for the Atari 8-bit and/or 5200. I know there's Adventure II and it's great but I was thinking of a game that would have the same low-res graphics as the original Adventure (as Indenture does) to save memory and therefore be able to have a large number of screens to explore. Galahad and the Holy Grail did this.

 

Has this already been done?

 

tjb

Link to comment
Share on other sites

How about the new kernel you made for Earthquake? He was doing some amazing stuff with that one.
Not flexible enough. The mixture of reflected/reversed patterns helps get a little closer (as does isloated placement of panels on those lines)...but too many rooms use patterns there's no good solution for.

 

 

Wouldn't it still be too many rooms though? I thought it was limited to 256 rooms and if I remember right Indenture has about 300 rooms.
The original game was limited to 32 rooms. The hack is limited to 128 rooms (or 256...if no level differences are present). This is only a limitation because that is the maximum amount of values that can be held in a single byte. We beat that restriction all the time in most games where you score points ;) Multiple variables to handle the problem. Another way (without wasting resources) would be to use redundant bankswitching to handle all rooms of a particular type in one bank, etc...for example, all "light" rooms in one, all "dark" rooms in another. Or all "inside" rooms vs. "outside" rooms...whatever. This makes for some clever coding tricks, because enemies could "see" more than a single room at one time (helping with the common problem of having too much ground for opponents to cover to provide any challenge). Object placement would need a bit of work (to prevent a key from showing up when you dropped it on a companion screen, etc), but nothing that would turn into a nightmare to code. Lookup tables are good at that sort of thing...and keeping dropped items' coordinates confined to even values gives you two extra bits to implement per object. That brings the total up to 1024 unique screens that any object can exist at using no advanced tricks.

 

The kernel is the main problem. If reproductions of such unsophisticated screens can't be 100% faithful, there's not much point. Bugfixing the game is also a problem...you get to know the mazes a bit -too- well for it to be any fun.

Link to comment
Share on other sites

The kernel is the main problem. If reproductions of such unsophisticated screens can't be 100% faithful, there's not much point. Bugfixing the game is also a problem...you get to know the mazes a bit -too- well for it to be any fun.

I suppose so. I remember Steve DeFrisco talking about Secret Quest saying that there could be a lot of rooms but they would all look the same. It seems like he could have followed Warren Robinett's pattern and made a better looking game than he did. After all, he had a lot more rom space to play with.

Link to comment
Share on other sites

The kernel is the main problem. If reproductions of such unsophisticated screens can't be 100% faithful, there's not much point.
It may be possible to do a 40-wide asymmertic playfield with two 2-line, single color sprites and the ball - assuming P1 and the ball are VDEL'ed. I haven't tried it, but with a 2-line kernel, assuming 48 cycles per line for the PF, there are 56 cycles left in which to draw the two players and the ball and any loop maintenance, which is a little tight but with skip/flip/switchdraw or similar techniques, it might barely work.

 

You would need 6 bytes for the extra pointers, so RAM may be an issue.

Link to comment
Share on other sites

You have to add in the problem that the playfield lines need a line counter just for that row of pixels (otherwise, there is extreme waste for empty rooms and such). That adds up to 3 skipdraws, 6 playfield indirect loads and stores using it's own Y, a counter update for the band height (AND'ed from PF0 data), and a total screen line counter.

 

(13+5)*3+(10*6+6)+12+8

 

Getting the playfield stores in time might be difficult. CTRLPF isn't needed, and neither are independant panels...so a little bit of savings there. I count about 12 cycles left out of 2 scanlines tops (assuming no WSYNCs are used). Save a few more if PF0 datas are shared in upper/lower nybbles.

Link to comment
Share on other sites

You have to add in the problem that the playfield lines need a line counter just for that row of pixels (otherwise, there is extreme waste for empty rooms and such). That adds up to 3 skipdraws, 6 playfield indirect loads and stores using it's own Y, a counter update for the band height (AND'ed from PF0 data), and a total screen line counter.

 

(13+5)*3+(10*6+6)+12+8

 

Getting the playfield stores in time might be difficult. CTRLPF isn't needed, and neither are independant panels...so a little bit of savings there. I count about 12 cycles left out of 2 scanlines tops (assuming no WSYNCs are used). Save a few more if PF0 datas are shared in upper/lower nybbles.

Just redo all rooms at 16 lines each row. It will use some extra space but one could put the graphics in a separate bank (or multiple banks with multiple kernel copies.) A separate Y can simply be ANDed off from a ZP value that holds the line counter.

 

It might work. I don't know how the Adventure kernel works but the above may require some setup or modification of pointers and graphics in order to work, but probably that's easier than adapting a kernel to Adventure's current kernel setup.

 

Now does someone want to try it?

 

EDIT: Here is a more detailed analysis with psuedocode. Line counter is in X.

 

Kernel_loop:

txa/tay (4 cycles)

switchdraw P0/P1 (30 cycles)

txa/and #$0f/tay (6 cycles)

Playfield (48 cycles)

skipdraw ball (only needs X - Y is preserved) (13 cycles)

Playfield (48 cycles)

dex/bne (6 cycles)

 

3 cycles to spare. It will require a copied PF for timing. I'm not sure how flexible the copied PF timing is, so this may require moving stuff around a little.

Edited by batari
Link to comment
Share on other sites

Might take a stab at it later...kind of busy now. But I really don't believe that it needs all of that waste. Should at least be possible by adding in a little bit of redundancy within the engine. Worst-case, set up 3 vectors that have been precalculated to call specific short kernel sections in order without needing skipdraw.

Link to comment
Share on other sites

  • 3 weeks later...

Without wasting ANY additional ram or relying on illegal opcodes, an asymmetrical playfield is possible (with panels and variable line counts) by blanking every other line. About the only drawback would be that objects cannot be hidden behind walls. Here's a pic of the latest binary I'm editing.

post-222-12510324241_thumb.jpg

Link to comment
Share on other sites

Without wasting ANY additional ram or relying on illegal opcodes, an asymmetrical playfield is possible (with panels and variable line counts) by blanking every other line. About the only drawback would be that objects cannot be hidden behind walls. Here's a pic of the latest binary I'm editing.

 

Looks nice! Another option would be to switch to a 3-line kernel; the playfield could be solid, and identical to the original if you change the frequency of playfield updates, although the player sprites would be stretched vertically.

 

--Will

post-23222-125104723508_thumb.png

Edited by e1will
Link to comment
Share on other sites

IMO an even better solution is to use 2 kernels (since both of them occupy less than a page of memory)...and have a flag decide on which to use. Asymmetrical data is very memory-consuming...and even Indenture doesn't need the capability for 3/4 of it's screens or so. I'm trying to keep the resources claimed by both identical. Leftover ram is better allocated to added objects, rather than the unchanging screen.

 

This is an example of how bloated lookup tables for such screens become:

 

;NOTE: Room definition data format is PF0,PF1,PF2,PF2,PF1,PF0
;      Lower nybble of 7th byte description:
;      Bit 0 (+$01) true if (R)eversed playfield
;      Bit 1 (+$02) true if left panel wanted
;      Bit 2 (+$04) true if playfield has priority over sprites (dark rooms, hide sprites)
;      Bit 3 (+$08) true if right panel wanted
;Scanline counts can be from 1 to 15...defined on the PREVIOUS line (the first line's count is
; fetched from the very first byte).
Room0F: ;White Castle (outside)
Room10: ;Black Castle (outside)
Room11: ;Yellow Castle (outside)
      .byte $F9,$FD,$0A,$0A,$FD,$FF;XXXXXXXXXX X X X        X X X XXXXXXXXXX - 9 2lk scanlines
      .byte $31,$07,$0F,$0F,$07,$3F;XX       XXXXXXX        XXXXXXX       XX - 15
      .byte $30,$07,$FF,$FF,$07,$32;XX       XXXXXXXXXXXXXXXXXXXXXX       XX - 15
      .byte $30,$01,$FF,$FF,$01,$32;XX         XXXXXXXXXXXXXXXXXX         XX - 2
      .byte $30,$00,$00,$00,$00,$32;XX                                    XX - 2
      .byte $30,$06,$12,$B2,$1C,$32;XX       XX  X  X   X XX  X   XXX     XX - 2
      .byte $30,$08,$B5,$AA,$04,$32;XX      X   X X XX XX X X X   X       XX - 2
      .byte $30,$04,$55,$AA,$0C,$32;XX       X  X X X X X X X X   XX      XX - 2
      .byte $30,$02,$17,$B2,$04,$32;XX        X XXX X   X XX  X   X       XX - 2
      .byte $30,$0C,$15,$A3,$1D,$32;XX      XX  X X X   X X   XXX XXX     XX - 2
      .byte $30,$00,$00,$00,$00,$32;XX                                    XX - 2
      .byte $30,$01,$FF,$FF,$01,$3F;XX         XXXXXXXXXXXXXXXXXX         XX - 2
      .byte $30,$01,$3F,$3F,$01,$3F;XX         XXXXXXX    XXXXXXX         XX - 15
      .byte $30,$00,$00,$00,$00,$39;XX                                    XX - 15
      .byte $F0,$FF,$0F,$0F,$FF,$F0;XXXXXXXXXXXXXXXX        XXXXXXXXXXXXXXXX - 9

Link to comment
Share on other sites

IMO an even better solution is to use 2 kernels (since both of them occupy less than a page of memory)...and have a flag decide on which to use. Asymmetrical data is very memory-consuming...and even Indenture doesn't need the capability for 3/4 of it's screens or so. I'm trying to keep the resources claimed by both identical. Leftover ram is better allocated to added objects, rather than the unchanging screen.

Using two kernels is an excellent idea.

 

Now, it's hard to be critical of such an ambitious project, especially since I know you have the talent to see it through.

 

But, I don't like your second kernel very much. While what you have done might be slightly easier to adapt to the existing code base, I think that using an interlaced display is not a very good compromise. Also, I don't think it will save space - in fact if you must encode a height for each row, it will probably use more data, not less. The extra screens all appear to use fixed vertical sizes for the pixels, so a kernel using fixed sizes would be better anyway, and could be written such that it does not need interlacing.

 

I also don't understand why you consider using undocumented opcodes is "resorting." Back in the day, programmers did have a discussion about using them and decided not to in case future revisions of the 2600 broke their code, but now we know that never happened (except for a handful of the more obscure opcodes on the FB2, which should not be much of a consideration, IMO.) Not using them today is purely academic.

Link to comment
Share on other sites

Now, it's hard to be critical of such an ambitious project, especially since I know you have the talent to see it through.
That makes one of us ;)

 

 

But, I don't like your second kernel very much. While what you have done might be slightly easier to adapt to the existing code base, I think that using an interlaced display is not a very good compromise.
I don't care for it much either...but there's no other way that I can find...currently. Ram must be saved at all cost, since Indenture's added objects demand so much. From what I can gather, I just -barely- have enough now to make it work pretty faithful to the original. The screen may not be as pretty, but it works. And that is job #1.

 

 

Also, I don't think it will save space - in fact if you must encode a height for each row, it will probably use more data, not less. The extra screens all appear to use fixed vertical sizes for the pixels, so a kernel using fixed sizes would be better anyway, and could be written such that it does not need interlacing.
That's a good point, but I'm not sure if all of the "multiple box" rooms can be done with mixtures of reflect & mirror yet (and those are 1/2 the resolution of the swiss cheese screens). As far as saving space goes, you only see this drop in rom savings wherever asymmetrical screens are concerned (the other kernel that does R&M saves a ton of rom)...throwing all of those screens into their own bank(s) is still a probability. No matter, since I'm not really concerned with saving rom at this point...I can add banks if I need 'em. The variable that does the counting is a shared one, so no loss of ram there...and as far as I can tell, it's operating at a 4-cycle difference between comparing a static value (the way the original game did) and one stored to temp ram. 1 cycle for the difference between immediate and zp addressing, and 3 more when storing the new value. Even taking all of that into account, I'd be seriously out of time trying to store the playfield data to temp ram (and since the existing stack only uses 4 bytes, there's an additional 2 bytes that I don't have to spare). Using static line counts for the asymmetrical kernel might be unavoidable, tho...if I can't scrape up the 4 (or possibly 2) cycles needed to kill the use of zero as the gfx delimiter.

 

 

I also don't understand why you consider using undocumented opcodes is "resorting."
I don't, really...but I still try never to use them if I can help it, or if the program routine in question isn't particularly demanding and a workaround is easily accomplished. I have a difficult enough time getting BIT instructions to read the way they are supposed to. Anything to avoid throwing in stuff that I don't fully comprehend. In the case of the latter, what I don't comprehend is why the instructions FAIL...and getting so hopelessly lost if/when they do that the hack is abandoned completely (I've done that a number of times).

 

 

 

Anyway...here's the current build of the kernel. The castles are the only screens using the new one...as a test. Looks to be operating smoothly. I had an issue earlier of the player square shinking as it was moved vertical, so I had to throw in a SEC instruction before the comparison (the other kernel, nope...it doesn't need it. And I don't know why the program treats them differently yet).

Adventure_asymmetrical.zip

Link to comment
Share on other sites

  • 3 weeks later...

I really like the idea of Indenture on the 2600... Sounds like the idea of a using a 3-line kernel for it was a non-starter, so I took the liberty of trying a 2-line kernel that might work without having to interlace.

 

It's actually a hybrid 4-line/2-line kernel: P1/P0/ball updates each 2 lines + PF updates each 4 lines (of course, 6 PF writes each line since it's asymmetrical.)

 

The pros are it works, and there are actually 20+ cycles free each loop for additional logic. And it's not TOO much of a RAM hog (doesn't require a PF index, for one thing.)

 

The cons are it requires a page per graphic image, which is a huge waste of ROM. On the upside, those 20+ cycles might be used to re-work it so it doesn't have to do that.

 

Thoughts?

post-23222-125247249724_thumb.png

asymtest.zip

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...