The room-drawing code

Discuss PoP1 for DOS here.
Post Reply
David
The Prince of Persia
The Prince of Persia
Posts: 2846
Joined: December 11th, 2008, 9:48 pm
Location: Hungary

The room-drawing code

Post by David »

I have converted the room drawing code from the disassembly into runnable C code. (Requires SDL)
I attached it to this post.

It helped me to find the cause of this bug: viewtopic.php?p=13913#p13913
It seems to me that the game first erases whatever is below the gate, then tries to redraw it, but this does not work for certain tiles.
You can see this in the original game if you start it with the "draw" command line option and decrease DOSBox's cycles to about 100-200 (or less).
I made a video about it, I attached it to this post.
Attachments
drawing.zip
Video about slowed-down room drawing.
(16.55 KiB) Downloaded 195 times
room-draw.zip
Room drawing in C.
(130.55 KiB) Downloaded 189 times
User avatar
Norbert
The Prince of Persia
The Prince of Persia
Posts: 5743
Joined: April 9th, 2009, 10:58 pm

Re: The room-drawing code

Post by Norbert »

Interesting video.
Must've been quite a bit of work to put that code together...
David
The Prince of Persia
The Prince of Persia
Posts: 2846
Joined: December 11th, 2008, 9:48 pm
Location: Hungary

Re: The room-drawing code

Post by David »

I forgot to tell: you can look at other rooms with the h-j-u-n keys, and go to the next level with L.
Also, data/levels/05mod has a room that demonstrates the bug with stacked gates.
Norbert wrote:Must've been quite a bit of work to put that code together...
Yes, it took me 2-3 days.

I spent much time with chasing stupid bugs, though.
For example:
Instead of this:

Code: Select all

if (tile == tiles_7_doortop_with_floor || tile == tiles_12_doortop) {
I accidentally wrote this:

Code: Select all

if (tile == tiles_7_doortop_with_floor || tiles_12_doortop) {
...and this caused the condition to be always true.

Another source of bugs was the signed-unsigned distinction.
The random_seed must be unsigned, or else some random numbers will be negative.
User avatar
Norbert
The Prince of Persia
The Prince of Persia
Posts: 5743
Joined: April 9th, 2009, 10:58 pm

Re: The room-drawing code

Post by Norbert »

The video that David attached to his first post:


Almost 6 years late, but for those who are interested in trying his program on Linux, here's a Makefile.

Code: Select all

# sudo apt install libsdl1.2-dev libsdl-image1.2-dev
# In all files, change the function name "random" to "randomr".
# In common.h + main.c change "#include <sdl/sdl.h>" to "#include <SDL/SDL.h>".
CC = gcc
CFLAGS = `sdl-config --cflags`
LIBS = `sdl-config --libs` -lSDL_image
TARGET = room-draw
OBJ = seg000.o seg007.o seg008.o seg009.o main.o
all: $(OBJ)
  $(CC) $(CFLAGS) -o $(TARGET) $(OBJ) $(LIBS)
David wrote: September 2nd, 2013, 9:16 am
Norbert wrote:Must've been quite a bit of work to put that code together...
Yes, it took me 2-3 days.
(I've commented on your work in the past, in other threads, but...)
That was very impressive, just 2-3 days!
The work sure paid off too, seeing how solid SDLPoP is now.
User avatar
atrueprincefanfrom18
Site Shah
Site Shah
Posts: 1782
Joined: January 21st, 2020, 2:53 pm
Contact:

Re: The room-drawing code

Post by atrueprincefanfrom18 »

Wow! It's nice to see such video outputs! :)
David wrote: September 2nd, 2013, 9:16 am I spent much time with chasing stupid bugs, though.
For example:
Instead of this:

Code: Select all

if (tile == tiles_7_doortop_with_floor || tile == tiles_12_doortop) {
I accidentally wrote this:

Code: Select all

if (tile == tiles_7_doortop_with_floor || tiles_12_doortop) {
...and this caused the condition to be always true.
Lol, it happens to me almost everytime :lol: My longest was 7 days to fix such bug!
Love to create new MODS :)

My complete list of mods until now!

My channel. Do consider subscribing it! :)
User avatar
dmitrys
Developer
Developer
Posts: 195
Joined: October 1st, 2020, 6:05 am

Re: The room-drawing code

Post by dmitrys »

I noticed a similar drawing bug with top gate corner that only happens in SDLPOP. It happens with the POP 1.3/1.4 dark dungeon palette (levels 8, 9 by default) where you have a gate right below the wall. The gate needs to open and close.
gate_draw_bug.png
The way the drawing algorithm works is a bit out of my expertise. It seems to happen in the following line of code. The reason is the black wall background which probably does not work well with the OR operator. My fix was changing the palette background color from rgb(0,0,0) to rgb(1,1,1). But the same palette works fine in the DOS version of POP.

Code: Select all

add_backtable(id_chtab_6_environment, door_fram_top[(modifier>>2) % 8], draw_xh, 0, draw_bottom_y, blitters_2_or, 0);
David
The Prince of Persia
The Prince of Persia
Posts: 2846
Joined: December 11th, 2008, 9:48 pm
Location: Hungary

Re: The room-drawing code

Post by David »

dmitrys wrote: October 3rd, 2020, 6:22 am I noticed a similar drawing bug with top gate corner that only happens in SDLPOP. It happens with the POP 1.3/1.4 dark dungeon palette (levels 8, 9 by default) where you have a gate right below the wall. The gate needs to open and close.
When method_3_blit_mono would draw the gate top mask (called here), the original image is completely black (palette index 0), and colored_image will be completely transparent.

Here is my fix: https://github.com/NagyD/SDLPoP/commit/ ... c6e3d7cbba

The new line mirrors this: https://github.com/NagyD/SDLPoP/blob/ma ... 009.c#L724

dmitrys wrote: October 3rd, 2020, 6:22 am The way the drawing algorithm works is a bit out of my expertise. It seems to happen in the following line of code.
The reason is the black wall background which probably does not work well with the OR operator.
SDLPoP doesn't do bitwise OR on the images, it's replaced with the transparent blitter.
dmitrys wrote: October 3rd, 2020, 6:22 am My fix was changing the palette background color from rgb(0,0,0) to rgb(1,1,1).
I can't reproduce this.
Which palette did you change?
* The palette in VDUNGEON.DAT?
* vga_color_0 in SDLPoP.ini?
* The palette in PRINCE.DAT? (level color variations.pal)
Color 0 for this color scheme is white originally. Color 1 is black. Did you change that?
* The palette in PRINCE.EXE?
User avatar
dmitrys
Developer
Developer
Posts: 195
Joined: October 1st, 2020, 6:05 am

Re: The room-drawing code

Post by dmitrys »

David wrote: October 24th, 2020, 1:56 pm
dmitrys wrote: October 3rd, 2020, 6:22 am My fix was changing the palette background color from rgb(0,0,0) to rgb(1,1,1).
I can't reproduce this.
Which palette did you change?
* The palette in VDUNGEON.DAT?
* vga_color_0 in SDLPoP.ini?
* The palette in PRINCE.DAT? (level color variations.pal)
Color 0 for this color scheme is white originally. Color 1 is black. Did you change that?
* The palette in PRINCE.EXE?
First of all, thank you for fixing all the issues I have found.

I changed the following values in SDLPoP code in the load_lev_spr(level) method, level colors section of the seg000.c for levels with the dark dungeon palette. The actual fix was a little more involved than just mutating the array but the code below should reproduce the fixed behavior. This problem does not happen in the DOS version.

Code: Select all

env_pal[3] = 0x01;
env_pal[4] = 0x01;
env_pal[5] = 0x01;
Post Reply