MPrince
MPrince
Greetings!
I want to share another one project of Prince of Persia.
Graphic Engine: SDL2.0
Language: C/C++
Windows / OS X support
Tasks have been done:
1. Drawing levels (Without random wall blocks)
2. Kid Animations (almost everything)
3. Kid Movements (almost everything)
3. Kid falling and y-velocity (x-vel not implemented yet)
4. Loosing board and flame as animations on level (examples)
5. Collisions (walls and near edge)
In progress:
1. Finally do collisions
2. Climbing on the wall
3. X-velocity for jumps
4. Random wall blocks (wda)
5. Objects on level like spikes, doors etc.
I'm going to publish sources on github soon.
Just doing it for fun.
https://www.youtube.com/watch?v=gmnKxUiy_bI
I want to share another one project of Prince of Persia.
Graphic Engine: SDL2.0
Language: C/C++
Windows / OS X support
Tasks have been done:
1. Drawing levels (Without random wall blocks)
2. Kid Animations (almost everything)
3. Kid Movements (almost everything)
3. Kid falling and y-velocity (x-vel not implemented yet)
4. Loosing board and flame as animations on level (examples)
5. Collisions (walls and near edge)
In progress:
1. Finally do collisions
2. Climbing on the wall
3. X-velocity for jumps
4. Random wall blocks (wda)
5. Objects on level like spikes, doors etc.
I'm going to publish sources on github soon.
Just doing it for fun.
https://www.youtube.com/watch?v=gmnKxUiy_bI
Last edited by jdbro on June 24th, 2019, 3:08 pm, edited 1 time in total.
Re: MPrince
Hi,
Could someone help me and explain purpose of fcheck values:
odd/even pixel - totally can't understand that
thin - (to "thin" this frame for collision detection) what is it?
xbase - number of pixels (0-31) from left edge of image block to base x-coord (where it can be used?)
thanks
Could someone help me and explain purpose of fcheck values:
odd/even pixel - totally can't understand that
thin - (to "thin" this frame for collision detection) what is it?
xbase - number of pixels (0-31) from left edge of image block to base x-coord (where it can be used?)
thanks
Re: MPrince
Another one question, can someone explain wall drawn algorithm (wda) (i hope @David)?
what i found of forum and in FormatSpecification by PrinceD development team, it's really hard to understand. If someone can explain it step by step, would be really great and helpful.
what i found of forum and in FormatSpecification by PrinceD development team, it's really hard to understand. If someone can explain it step by step, would be really great and helpful.
Re: MPrince
The DOS version doesn't use this at all. You probably won't need it either.
It is used the Apple II version (here) to offset the image to the right by one pixel.
It means to move the left and right edges of the hitbox inwards (by 3 or 4 pixels, depending on which version of the game it is).
The default edges are at the edges of the current image of the Prince.
See Apple II source here and SDLPoP source here.
It is used, for example, to determine which tile is currently pressed down by the Prince.
Re: MPrince
David, thank you for answers!
Thanks!
What is the purpose on the Apple II version ?
I see, but why do we need this? could you give example? 4 pixels = DOS Version and 3 ?David wrote: It means to move the left and right edges of the hitbox inwards (by 3 or 4 pixels, depending on which version of the game it is).
The default edges are at the edges of the current image of the Prince.
See Apple II source here and SDLPoP source here.
still can't understand, we can check tile under prince without that, why do we need this xbase and how properly calculate it?David wrote: It is used, for example, to determine which tile is currently pressed down by the Prince.
Thanks!
Re: MPrince
To follow some of my explanations below, you should download this: viewtopic.php?p=15726#p15726
It contains a listing of the frame table and the sequence table. (seqHEX.htm)
(odd/even pixel)
What I do know is that on the Apple II, if an image is offset by one pixel horizontally then some colors will change.
In the case of PoP, orange will become blue and vice versa.
(thin)
The frame table shows it's used only for a couple of the frames. (For 16 frames of 241 to be exact. Look for "THIN=1" in seqHEX.htm.)
(xbase)
For example, look at two adjacent frames from the safe-step (in seqHEX.htm again):
* frame 0x7E has xbase=15, because the prince hasn't put his left foot down yet, and he's standing on his right foot.
* frame 0x7F has xbase=3, because he now put his left foot down, and he lifted his right foot.
When the prince steps onto a button, this is the exact moment when the button gets pressed.
(By the way, xbase is counted in two-pixel units.)
Here is an illustration of the above:
It contains a listing of the frame table and the sequence table. (seqHEX.htm)
(odd/even pixel)
I don't know why didn't they just move the image itself by one pixel.
What I do know is that on the Apple II, if an image is offset by one pixel horizontally then some colors will change.
In the case of PoP, orange will become blue and vice versa.
(thin)
I don't know why it's done.
The frame table shows it's used only for a couple of the frames. (For 16 frames of 241 to be exact. Look for "THIN=1" in seqHEX.htm.)
3 is used in the Apple II version.
(xbase)
Because the game needs to know which part of the prince is pressing the floor, in case his sprite touches two adjacent tiles at the same time.
For example, look at two adjacent frames from the safe-step (in seqHEX.htm again):
* frame 0x7E has xbase=15, because the prince hasn't put his left foot down yet, and he's standing on his right foot.
* frame 0x7F has xbase=3, because he now put his left foot down, and he lifted his right foot.
When the prince steps onto a button, this is the exact moment when the button gets pressed.
(By the way, xbase is counted in two-pixel units.)
Here is an illustration of the above:
You don't need to calculate it, it's already in the frame table.
Re: MPrince
David, thanks for answer, it's really brilliant.
Let me try to summarize.
Xbase is used for frames when we need to check which part of frame is on the floor when FLOOR = 1.
Something like "fulcrum".
For example:
if the raise/drop button under prince and frame is 0x7E we should check (KIDFRAME_WIDTH - XBASE*2) part (if KID looks left). Same for 0x7F.
Am i right?
But, we have frames with FLOOR = 0, for example 0x2A, what do we check there?
frame 0x2A CHTABLE=0 IMAGE= 41 SWORD= 0 DX= 0 DY= 0 OE=1 FLOOR=0 THIN=0 XBASE=10 Thanks again!
p.s.
Let me try to summarize.
Xbase is used for frames when we need to check which part of frame is on the floor when FLOOR = 1.
Something like "fulcrum".
For example:
if the raise/drop button under prince and frame is 0x7E we should check (KIDFRAME_WIDTH - XBASE*2) part (if KID looks left). Same for 0x7F.
Am i right?
But, we have frames with FLOOR = 0, for example 0x2A, what do we check there?
frame 0x2A CHTABLE=0 IMAGE= 41 SWORD= 0 DX= 0 DY= 0 OE=1 FLOOR=0 THIN=0 XBASE=10 Thanks again!
p.s.
two-pixel or (320/140) coefficient ?David wrote: (By the way, xbase is counted in two-pixel units.)
Re: MPrince
Yes.
Not exactly.
According to the SDLPoP source, the X coordinate to be checked is calculated this way:
If kid is facing left : X = Char.x - (dx - xbase) = Char.x - dx + xbase
If kid is facing right: X = Char.x + (dx - xbase) = Char.x + dx - xbase
All these values are measured in the logical coordinate system in which a room is 140 units wide.
The width of the current frame is not used here.
Note that if the kid is facing right, his sprite is mirrored around its left edge (not around its middle).
In that case, the prince doesn't press any tile.
I don't know why is XBASE non-zero for this frame.
The latter.
More precisely, xbase (and the kid's x-position) is measured in the logical coordinate system in which a room is 140 units wide.
Re: MPrince
David wrote: If kid is facing left : X = Char.x - (dx - xbase) = Char.x - dx + xbase
If kid is facing right: X = Char.x + (dx - xbase) = Char.x + dx - xbase
David wrote: (By the way, xbase is counted in two-pixel units.)
jdbro wrote: two-pixel or (320/140) coefficient ?
Thank you again for detailed answers.David wrote: The latter.
More precisely, xbase (and the kid's x-position) is measured in the logical coordinate system in which a room is 140 units wide.
So if we are talking about DOS resolution, eventually we can X multiply by 320/140 coefficient ?
char.x, dx and xbase are designed for 140 units wide resolution. am i right?
And one final question about even/odd pixel, i've found in SDLPoP that you are using it.
https://github.com/NagyD/SDLPoP/blob/ma ... 08.c#L1720
void __pascal far load_frame_to_obj() {
word chtab_base;
chtab_base = id_chtab_2_kid;
reset_obj_clip();
load_frame();
obj_direction = Char.direction;
obj_id = cur_frame.image;
// top 6 bits of sword are the chtab
obj_chtab = chtab_base + (cur_frame.sword >> 6);
obj_x = (char_dx_forward(cur_frame.dx) << 1) - 116;
obj_y = cur_frame.dy + Char.y;
if ((sbyte)(cur_frame.flags ^ obj_direction) >= 0) {
// 0x80: even/odd pixel
++obj_x;
}
}
What is the purpose?
Thanks!
Re: MPrince
You're right. I overlooked that line because it doesn't use the FRAME_EVEN_ODD_PIXEL constant defined in types.h.jdbro wrote: ↑July 6th, 2019, 12:31 pm And one final question about even/odd pixel, i've found in SDLPoP that you are using it.
https://github.com/NagyD/SDLPoP/blob/ma ... 08.c#L1720
Maybe I should rewrite that line to use the constant?
The code pushes the sprite one unit to the right if either direction=left (0xFF) and evenodd bit=1 or direction=right (0x00) and evenodd bit=0.
Again, this code was inherited from the Apple II version.
If you mirror a sprite around its left edge (the left edge of its leftmost pixel column), then pixels with an even X coordinate will end up at odd X coordinates and vice versa.
On the Apple II screen, this would swap orange and blue. That's why the code is sensitive to the direction of the sprite.
But I still don't know why Mechner attached an evenodd bit to frames, instead of offsetting those images by one pixel.
While at it:
In case of the kid and the guards, obj_x contains the X coordinate on a 280 units wide screen (suitable for the Apple II), to be converted by calc_screen_x_coord() later.
But for the sword in someone's hand, obj_x is the X coordinate on a 320 units wide screen, already converted using calc_screen_x_coord().
Re: MPrince
Thank you, David! very helpful.
One thing that really hard to understand from code is wda, could i ask you to explain wda ? (wall drawn algorithm), as i heard there were 63 different variations.
One thing that really hard to understand from code is wda, could i ask you to explain wda ? (wall drawn algorithm), as i heard there were 63 different variations.
Re: MPrince
Wow. David is the Einstein of PoP!David wrote: ↑July 7th, 2019, 12:13 pmYou're right. I overlooked that line because it doesn't use the FRAME_EVEN_ODD_PIXEL constant defined in types.h.jdbro wrote: ↑July 6th, 2019, 12:31 pm And one final question about even/odd pixel, i've found in SDLPoP that you are using it.
https://github.com/NagyD/SDLPoP/blob/ma ... 08.c#L1720
Maybe I should rewrite that line to use the constant?
The code pushes the sprite one unit to the right if either direction=left (0xFF) and evenodd bit=1 or direction=right (0x00) and evenodd bit=0.
Again, this code was inherited from the Apple II version.
If you mirror a sprite around its left edge (the left edge of its leftmost pixel column), then pixels with an even X coordinate will end up at odd X coordinates and vice versa.
On the Apple II screen, this would swap orange and blue. That's why the code is sensitive to the direction of the sprite.
But I still don't know why Mechner attached an evenodd bit to frames, instead of offsetting those images by one pixel.
While at it:
In case of the kid and the guards, obj_x contains the X coordinate on a 280 units wide screen (suitable for the Apple II), to be converted by calc_screen_x_coord() later.
But for the sword in someone's hand, obj_x is the X coordinate on a 320 units wide screen, already converted using calc_screen_x_coord().
Re: MPrince
Work in progress.
https://youtu.be/Xhjd5pf6Cm4
Tasks have been done:
1. Realtime collisions (not tile checking, took me 2 months to make that, because it was really pain in the ass to calculate pixels on every action with tile approach)
2. Climbing on the wall
3. Objects on level like spikes, doors, swords etc.
4. Guards
ToDo:
1. WDA (wall drawn algorithm) - still looking for help if someone could explain, would be awesome
2. Fight Animations and Guard AI
3. Special Events on levels
https://youtu.be/Xhjd5pf6Cm4
Tasks have been done:
1. Realtime collisions (not tile checking, took me 2 months to make that, because it was really pain in the ass to calculate pixels on every action with tile approach)
2. Climbing on the wall
3. Objects on level like spikes, doors, swords etc.
4. Guards
ToDo:
1. WDA (wall drawn algorithm) - still looking for help if someone could explain, would be awesome
2. Fight Animations and Guard AI
3. Special Events on levels
Re: MPrince
Remade almost everything with modern techniques. Original code is awful and so hard to do something with that, pixel hunting is everywhere!
Soon i'll try to share my one year experience.
Soon i'll try to share my one year experience.