Unused Citadel bits

reminisce about classic bbc micro and acorn electron games here
Related forum: adventures


User avatar
scarybeasts
Posts: 560
Joined: Tue Feb 06, 2018 7:44 am
Contact:

Re: Unused Citadel bits

Post by scarybeasts » Fri Oct 16, 2020 9:17 am

Diminished wrote:
Fri Oct 16, 2020 8:54 am
This is interesting.

From memory, it does something like reprogram the CRTC to limit the visible screen area to the first few lines (the ones that contain the header text and inventory sprites) while it invisibly redraws the room. Then it switches it back to full screen afterwards. I'm not sure why this might cause different behaviour on an LCD compared to a CRT -- any theories, anyone?
I'm pretty sure there's a race condition in the way it reprograms the CRTC. If you look at my "beebjit turbo collage" video here:
https://www.youtube.com/watch?v=Fr-IZAb5Gj8

Citadel is in the top left and you can see the top of the screen getting corrupted regularly. The framing of the corrupted screens looks pretty wild -- perhaps vsync is firing in the middle of the displayed data.


Cheers
Chris

User avatar
Rich Talbot-Watkins
Posts: 1662
Joined: Thu Jan 13, 2005 5:20 pm
Location: Palma, Mallorca
Contact:

Re: Unused Citadel bits

Post by Rich Talbot-Watkins » Sat Oct 17, 2020 7:13 am

That's weird. From Diminished's disassembly, I only see it setting CRTC R6 (vertical displayed) to 2 while it redraws the screen - nothing there which would affect VSync, or have that kind of strange effect. It also plays with R5 (vertical adjust) during gameplay, to shake the screen when the player falls from a height, but I don't think that would be getting invoked during the attract mode.

User avatar
scarybeasts
Posts: 560
Joined: Tue Feb 06, 2018 7:44 am
Contact:

Re: Unused Citadel bits

Post by scarybeasts » Sat Oct 17, 2020 7:45 am

Rich Talbot-Watkins wrote:
Sat Oct 17, 2020 7:13 am
That's weird. From Diminished's disassembly, I only see it setting CRTC R6 (vertical displayed) to 2 while it redraws the screen - nothing there which would affect VSync, or have that kind of strange effect. It also plays with R5 (vertical adjust) during gameplay, to shake the screen when the player falls from a height, but I don't think that would be getting invoked during the attract mode.
This is speculating wildly (i.e. I've been too lazy to trap the condition in the debugger).
But you'll get weirdness if the vertical counter is >2 and <R6 at the time R6 is set to 2. For the rest of that CRTC frame, display will remain enabled. When R7 (vsync) hits, display will still be on so you'd get rendering at the top of the CRT area.

For most transitions, there's no weirdness -- so perhaps an attempt is made to set R6 at a sane juncture, but some IRQ or other race condition knocks it out from time to time.


Cheers
Chris

User avatar
Rich Talbot-Watkins
Posts: 1662
Joined: Thu Jan 13, 2005 5:20 pm
Location: Palma, Mallorca
Contact:

Re: Unused Citadel bits

Post by Rich Talbot-Watkins » Sat Oct 17, 2020 7:55 am

Hmm, true. I don't think there's any synchronisation with vsync at all, so it could indeed happen at any moment and result in the occasional frame without vertical display disable. Perhaps some monitors expect no signal during vsync, and won't sync if there is.

User avatar
Diminished
Posts: 522
Joined: Fri Dec 08, 2017 9:47 pm
Contact:

Re: Unused Citadel bits

Post by Diminished » Sat Oct 17, 2020 11:03 am

Hmm... As well as the two explicit OSBYTEs (one before update_player and the other associated with firing the cannon), there is also the master_speed_wait function, which checks num_irqs_counter, a variable which I think is incremented on vsync?

The main game loop and the attract mode are distinct, too. The main loop explicitly syncs before update_player. The attract mode loop never does, but it does invoke master_speed_wait.

I'd guess the two game modes would cause corruption in different ways.

Eyeballing it, the main game process for a room change is like

- 42f8: P_main_main, top of loop
- 4394: explicit vsync wait before update_player
- entire frame's worth of logic happens; let's assume the player moves offscreen
- 43d5: master_speed_wait called, which waits for multiple frames based on num_irqs_counter, which I think is incremented on vsync? so sync happens here too?
- 43d8: animate_a is called
- 43e5: jump to P_main_main
- 42f8: P_main_main (again)
- 434a: room change detected at top of main loop, jump to before P_main_main, to P_main_roomchange
- 42ab: P_main_roomchange
- 42d3: calls super_draw_room
- 42f5: calls blit_player_anim to redraw player
- 42f8: falls back through to P_main_main (yet again)

The attract mode does

- 426d: { P_attract_inner, calls master_speed_wait, syncs here?
- 4270: calls animate_a
- 4281: keep jumping to P_attract_inner until room has expired }
- 4283: once room has expired, jump to P_attract_outer instead
- 424d: P_attract_outer
- 4266: calls super_draw_room

I dunno. Presumably animate_a takes a variable length of time depending on how much stuff there is in the room, and in both cases that seems to be the routine which splits master_speed_wait and super_draw_room.

The implication by j6wbs (or perhaps just my inference) was that the corruption seen was happening on every room change, though, rather than just periodically.

j6wbs
Posts: 11
Joined: Tue Feb 02, 2016 8:11 am
Contact:

Re: Unused Citadel bits

Post by j6wbs » Sat Oct 17, 2020 11:34 am

Hi,
Yes, it does seem to happen on every room change.

Thanks for looking so deeply into it, I imagine the issue is more to do with the HDMI scaling that the TV/MiSTer is doing or something similar, however in the interests of completeness I have posted a short video of the issue as a much better description than my words can ever be....
https://www.youtube.com/watch?v=Ygha48sWG7k
Filmed using a recent BBC Micro core on the MiSTer, using HDMI into flat panel TV.

As I mentioned, the CRT display from the MiSTer is rock solid on each room change, so I think it is probably scaler related.
Weird behaviour though...

Cheers

Jez (j6wbs)

User avatar
Diminished
Posts: 522
Joined: Fri Dec 08, 2017 9:47 pm
Contact:

Re: Unused Citadel bits

Post by Diminished » Sat Oct 17, 2020 11:51 am

j6wbs wrote:
Sat Oct 17, 2020 11:34 am
...
Oh, that's cool. Not what I expected!

User avatar
Diminished
Posts: 522
Joined: Fri Dec 08, 2017 9:47 pm
Contact:

Re: Unused Citadel bits

Post by Diminished » Fri Oct 23, 2020 11:31 pm

  • stars fixed (stupid scoping mistake)
  • doors are done (command-line switches for locked, unlocked or open)
  • items can now be placed on item pads (fixed some bugs in branch B of the tile drawing routine; coded some hitherto unimplemented entrypoints which adjust the plot position based on the size of the item in order to align it to the pad)
  • pillars done (had to fix another stupid bug in reading MODE 2 style pixels from the new chunky collision buffer)
STALAGTITES AND STALAGMITES
Ropes, pillars and ladders are similar in certain ways, but ultimately different in others. All three are drawn procedurally to permit a variable length without bloating the room data.

Ropes and pillars don't have a length associated with them. They are placed at a coordinate and then just "grow" until they encounter some nonzero collision, whereupon they stop. A pillar's origin is at its top, and it grows downwards until it hits something. A rope's origin is at its base, and it grows upwards until it hits something. This behaviour makes sense, since you want ropes to be able to dangle in mid-air, but for them always to be attached to something at the top. So, you can't place a rope that isn't attached to anything!

Ladders are different; they seem to use an explicit length parameter. They grow upwards, like the ropes do. At first I wondered why they weren't made to grow downwards and stop on collision, since I believe all ladders in the game rest on a floor -- there aren't any "rope ladders" whose bottom rung is in mid-air. This would obviate the need for the length parameter. However, I'm guessing the idea is that you can use a ladder to automatically cut a hole through a wall you've already drawn, whereas a rope would just halt on the collision in this case. Hence, although a rope and a ladder work the same way from the player's point of view, they are not equivalent.



I've reached an interesting juncture with this code now. All of the static elements of the rooms are implemented and seem to draw correctly. This doesn't mean I have the room format completely implemented yet, because of course the room bytecode also defines all the various animations that are cycled during gameplay, which are dealt with by the subroutine I called animate. Implementing these doesn't seem to make much sense yet, since the code just spits out a single image file; there is no way to output multiple frames. It could be modified to do this, but there's not a lot of sense in it, since certain animations (e.g. the creatures which chase the player) are modulated by the player's current position.

There is a lot of cleanup work to be done, and I want to try to "decouple" as much of the code as I can. Data flows are performed through simulated zero-page variables used by the game itself, which was a deliberate choice to guarantee that the thing would work. Many of these are "foo/bar"-style variables which are used for different purposes depending on which routine is currently executing. I want to get rid of those, to rename everything logically, and to try to rework everything in a more functional style in which routines have well-defined input and output parameters, which was really the whole point of doing this in the first place. Fortunately this should now be easy, because I have a reference implementation, and so any change which breaks something will be trivial to detect.

The question is where to go with it after that. Originally I was thinking about doing an enhanced reimplementation for modern OSes in C. Now I am wondering if making something that runs in a browser instead might be a more interesting route, when you consider possibilities like level editing, or animated, real-time, pictorial demonstrations of how things are drawn.

Dunno!

Post Reply

Return to “8-bit acorn software: classic games”