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.
The room-drawing code
The room-drawing code
- Attachments
-
- drawing.zip
- Video about slowed-down room drawing.
- (16.55 KiB) Downloaded 197 times
-
- room-draw.zip
- Room drawing in C.
- (130.55 KiB) Downloaded 192 times
Re: The room-drawing code
Interesting video.
Must've been quite a bit of work to put that code together...
Must've been quite a bit of work to put that code together...
Re: The room-drawing code
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.
I spent much time with chasing stupid bugs, though.
For example:
Instead of this:
I accidentally wrote this:
...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.
Also, data/levels/05mod has a room that demonstrates the bug with stacked gates.
Yes, it took me 2-3 days.Norbert wrote:Must've been quite a bit of work to put that code together...
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) {
Code: Select all
if (tile == tiles_7_doortop_with_floor || tiles_12_doortop) {
Another source of bugs was the signed-unsigned distinction.
The random_seed must be unsigned, or else some random numbers will be negative.
Re: The room-drawing code
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.
That was very impressive, just 2-3 days!
The work sure paid off too, seeing how solid SDLPoP is now.
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)
(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.
- atrueprincefanfrom18
- Site Shah
- Posts: 1785
- Joined: January 21st, 2020, 2:53 pm
- Contact:
Re: The room-drawing code
Wow! It's nice to see such video outputs!
Lol, it happens to me almost everytime My longest was 7 days to fix such bug!David wrote: ↑September 2nd, 2013, 9:16 am I spent much time with chasing stupid bugs, though.
For example:
Instead of this:I accidentally wrote this:Code: Select all
if (tile == tiles_7_doortop_with_floor || tile == tiles_12_doortop) {
...and this caused the condition to be always true.Code: Select all
if (tile == tiles_7_doortop_with_floor || tiles_12_doortop) {
Re: The room-drawing code
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.
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.
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);
Re: The room-drawing code
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
SDLPoP doesn't do bitwise OR on the images, it's replaced with the transparent blitter.
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?
Re: The room-drawing code
First of all, thank you for fixing all the issues I have found.David wrote: ↑October 24th, 2020, 1:56 pmI 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?
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;