Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Libretro
cannonball
Commits
ea67c5dd
Commit
ea67c5dd
authored
Feb 26, 2013
by
reassembler
Browse files
Road Path Cleanup (Not complete)
parent
dd989809
Changes
2
Hide whitespace changes
Inline
Side-by-side
src/main/engine/oroad.cpp
View file @
ea67c5dd
...
...
@@ -11,6 +11,9 @@
This is the most complex area of the game code, and an area of the code
in need of refactoring.
Useful background reading on road rendering:
http://www.extentofthejam.com/pseudo/
Copyright Chris White.
See license.txt for more details.
***************************************************************************/
...
...
@@ -86,16 +89,6 @@ void ORoad::init()
road_pos_old
=
0
;
road_data_offset
=
0
;
curve_x1_diff
=
0
;
curve_x2_diff
=
0
;
curve_x1_dist
=
0
;
curve_x2_dist
=
0
;
curve_x1_next
=
0
;
curve_x2_next
=
0
;
curve_inc_old
=
0
;
curve_start
=
0
;
curve_inc
=
0
;
curve_end
=
0
;
height_start
=
0
;
height_ctrl
=
0
;
pos_fine_old
=
0
;
...
...
@@ -284,6 +277,7 @@ void ORoad::setup_road_x()
if
(
road_pos_change
!=
0
)
{
road_data_offset
=
(
road_pos
>>
16
)
<<
2
;
set_tilemap_x
();
setup_x_data
();
}
setup_hscroll
();
...
...
@@ -337,31 +331,14 @@ void ORoad::setup_x_data()
{
uint32_t
addr
=
stage_addr
+
road_data_offset
;
// d0 = road_x1 + road_x1_next [x difference]
curve_x1_diff
=
roms
.
rom1p
->
read16
(
addr
);
curve_x1_diff
+=
(
int16_t
)
roms
.
rom1p
->
read16
(
addr
+
4
);
// d1 = x2 difference
curve_x2_diff
=
roms
.
rom1p
->
read16
(
addr
+
2
);
curve_x2_diff
+=
(
int16_t
)
roms
.
rom1p
->
read16
(
addr
+
6
);
int32_t
distance
=
(
curve_x1_diff
*
curve_x1_diff
)
+
(
curve_x2_diff
*
curve_x2_diff
);
// The distance formula in Cartesian coordinates is derived from the Pythagorean theorem
// Use Pythagorus' theorem to find the distance between point 1 & point 2
// Result stored in d0 [distance]
distance
=
(
uint16_t
)
outils
::
isqrt
(
distance
);
const
int16_t
x
=
(
int16_t
)
roms
.
rom1p
->
read16
(
addr
)
+
(
int16_t
)
roms
.
rom1p
->
read16
(
addr
+
4
);
// Length 1
const
int16_t
y
=
(
int16_t
)
roms
.
rom1p
->
read16
(
addr
+
2
)
+
(
int16_t
)
roms
.
rom1p
->
read16
(
addr
+
6
);
// Length 2
int32_t
d2
=
(
curve_x1_diff
<<
14
);
// extend to 32
int
32
_t
d
3
=
(
curve_x2_diff
<<
14
);
// extend to 32
// Use Pythagorus' theorem to find the distance/length between x & y
const
u
int
16
_t
d
istance
=
outils
::
isqrt
((
x
*
x
)
+
(
y
*
y
));
// divide x,y
// source x (16-bit), destination y (32-bit)
// result y (32-bit). Remainder is upper 16 bits.
curve_x1_dist
=
d2
/
distance
;
// here we only care about the lower 16 bits
curve_x2_dist
=
d3
/
distance
;
set_tilemap_x
();
const
int16_t
curve_x_dist
=
(
x
<<
14
)
/
distance
;
// Scale up is for fixed point division in create_curve
const
int16_t
curve_y_dist
=
(
y
<<
14
)
/
distance
;
// Setup Default Straight Positions Of Road at 60800 - 608FF
for
(
uint8_t
i
=
0
;
i
<
0x80
;)
...
...
@@ -372,27 +349,29 @@ void ORoad::setup_x_data()
}
// Now We Setup The Real Road Data at 60800
curve_x1_next
=
0
;
curve_x2_next
=
0
;
curve_inc_old
=
0
;
curve_start
=
0
;
int32_t
curve_x_total
=
0
;
int32_t
curve_y_total
=
0
;
int16_t
curve_start
=
0
;
int16_t
curve_end
=
0
;
int16_t
curve_inc
=
0
;
int16_t
curve_inc_old
=
0
;
int16_t
scanline
=
0x37E
/
2
;
// Index into road_x
uint8_t
road_x_addr
=
0
;
// Note this works its way from closest to the camera, further into the horizon
// So the amount to offset x is going to increase over time
// We sample 20 Road Positions to generate the road.
for
(
uint8_t
i
=
0
;
i
<=
0x20
;
i
++
)
{
int32_t
x
1
_next
=
(
int16_t
)
roms
.
rom1p
->
read16
(
&
addr
);
int32_t
x2
_next
=
(
int16_t
)
roms
.
rom1p
->
read16
(
&
addr
);
x1_next
+=
(
int16_t
)
roms
.
rom1p
->
read16
(
&
addr
)
;
x2_next
+=
(
int16_t
)
roms
.
rom1p
->
read16
(
&
addr
);
curve_x
1_next
+=
x
1
_next
;
curve_
x2_next
+=
x2
_next
;
const
int32_t
x_next
=
(
int16_t
)
roms
.
rom1p
->
read16
(
addr
)
+
(
int16_t
)
roms
.
rom1p
->
read16
(
addr
+
4
);
// Length 1
const
int32_t
y
_next
=
(
int16_t
)
roms
.
rom1p
->
read16
(
addr
+
2
)
+
(
int16_t
)
roms
.
rom1p
->
read16
(
addr
+
6
);
// Length 2
addr
+=
8
;
curve_x
_total
+=
x_next
;
curve_
y_total
+=
y
_next
;
// Calculate curve increment and end position
create_curve
();
create_curve
(
curve_inc
,
curve_end
,
curve_x_total
,
curve_y_total
,
curve_x_dist
,
curve_y_dist
);
int16_t
curve_steps
=
curve_end
-
curve_start
;
if
(
curve_steps
<
0
)
return
;
if
(
curve_steps
==
0
)
continue
;
// skip_pos
...
...
@@ -406,7 +385,7 @@ void ORoad::setup_x_data()
x
+=
xinc
;
if
(
x
<
-
0x3200
||
x
>
0x3200
)
return
;
road_x
[
scanline
]
=
x
;
if
(
--
scanline
<
0
)
return
;
if
(
--
scanline
<
0
)
return
;
}
curve_inc_old
=
curve_inc
;
...
...
@@ -414,6 +393,25 @@ void ORoad::setup_x_data()
}
}
// Interpolates road data into a smooth curve.
//
// Source Address: 0x16B6
void
ORoad
::
create_curve
(
int16_t
&
curve_inc
,
int16_t
&
curve_end
,
int32_t
curve_x_total
,
int32_t
curve_y_total
,
int16_t
curve_x_dist
,
int16_t
curve_y_dist
)
{
// Note multiplication result should be 32bit, inputs 16 bit
int32_t
d0
=
((
curve_x_total
>>
5
)
*
curve_y_dist
)
-
((
curve_y_total
>>
5
)
*
curve_x_dist
);
int32_t
d2
=
((
curve_x_total
>>
5
)
*
curve_x_dist
)
+
((
curve_y_total
>>
5
)
*
curve_y_dist
);
d2
>>=
7
;
int32_t
d1
=
(
d2
>>
7
)
+
0x410
;
curve_inc
=
d0
/
d1
;
// Total amount to increment x by
curve_end
=
(
d2
/
d1
)
*
4
;
}
// Set The Correct Tilemap X *target* Position From The Road Data
//
// Source Address: 0x16F6
...
...
@@ -485,32 +483,6 @@ void ORoad::set_tilemap_x()
tilemap_h_target
=
scroll_x
;
}
// Interpolates road data into a smooth curve.
//
// Source Address: 0x16B6
void
ORoad
::
create_curve
()
{
// Note multiplication result should be 32bit, inputs 16 bit
int32_t
d0
=
((
curve_x1_next
>>
5
)
*
curve_x2_dist
);
int32_t
d1
=
((
curve_x2_next
>>
5
)
*
curve_x1_dist
);
int32_t
d2
=
((
curve_x1_next
>>
5
)
*
curve_x1_dist
);
int32_t
d3
=
((
curve_x2_next
>>
5
)
*
curve_x2_dist
);
d0
-=
d1
;
d2
+=
d3
;
d2
>>=
7
;
d1
=
d2
;
d1
>>=
7
;
d1
+=
0x410
;
d0
=
d0
/
d1
;
d2
=
d2
/
d1
;
curve_inc
=
d0
;
// truncates to int16
curve_end
=
d2
*
4
;
// truncates to int16
}
// Creates the bend in the next section of road.
//
// Source Address: 0x180C
...
...
@@ -565,7 +537,7 @@ void ORoad::do_road_offset(int16_t* dst_x, int16_t width, bool invert)
int32_t
car_offset
=
car_x_bak
+
width
+
oinitengine
.
camera_x_off
;
// note extra debug of camera x
int32_t
scanline_inc
=
0
;
// Total amount to increment scanline (increased every line)
int16_t
*
src_x
=
road_x
;
// a0
/*
// ---------------------------------------------------------------
// Process H-Scroll: Car not central on road 0
// The following loop ensures that the road offset
...
...
@@ -600,7 +572,7 @@ void ORoad::do_road_offset(int16_t* dst_x, int16_t width, bool invert)
// ------------------------------
// Ignore Car Position / H-Scroll
// ------------------------------
*/
if
(
!
invert
)
{
for
(
uint16_t
i
=
0
;
i
<=
0x3F
;
i
++
)
...
...
src/main/engine/oroad.hpp
View file @
ea67c5dd
...
...
@@ -11,10 +11,14 @@
This is the most complex area of the game code, and an area of the code
in need of refactoring.
Useful background reading on road rendering:
http://www.extentofthejam.com/pseudo/
Copyright Chris White.
See license.txt for more details.
***************************************************************************/
#pragma once
class
ORoad
...
...
@@ -94,6 +98,10 @@ public:
// Once the distance is greater than F0 or so, it's obvious there are two independent roads.
int32_t
road_width
;
// DANGER! USED AS LONG AND WORD
// 0x420: Offset Into Road Data [Current Road Position * 4]
// Moved from private for tracked
uint16_t
road_data_offset
;
// 0x4F0: Start Address of Road Data For Current Stage In ROM
// TODO - move back to being private at some stage
uint32_t
stage_addr
;
...
...
@@ -151,33 +159,6 @@ private:
uint32_t
road_pos_old
;
// 0x410: Road Position Backup
// 0x420: Offset Into Road Data [Current Road Position * 4]
uint16_t
road_data_offset
;
// 0x450 - [word] Curve x1 Difference FIRST [Note this is the first position of the road segment]
int16_t
curve_x1_diff
;
// 0x460 - [word] Curve x2 Difference FIRST (e.g. length of segment) [Note this is the first position of the road segment]
int16_t
curve_x2_diff
;
// 0x470 - [word] Curve x1 Distance [Note this is the first position of the road segment]
int16_t
curve_x1_dist
;
// 0x480 - [word] Curve x2 Distance [Note this is the first position of the road segment]
int16_t
curve_x2_dist
;
// 0x490 - [long] Curve x1 Difference NEXT [This can be any position of the road segment, not just the first]
int32_t
curve_x1_next
;
// 0x4a0 - [long] Curve x2 Difference NEXT (e.g. length of road segment)
int32_t
curve_x2_next
;
// 0x4b0 - [word] Curve Increment Previous
int16_t
curve_inc_old
;
// 0x4c0 - [word] Curve Start (Used to calculate number of steps)
int16_t
curve_start
;
// 0x4d0 - [word] Curve Increment
int16_t
curve_inc
;
// 0x4E0 - [word] Curve End (Used to calculate number of steps)
int16_t
curve_end
;
// 60530 - [word] Distance into section of track, for height #1
// Ranges from 0x100 - 0x1FF
uint16_t
height_start
;
...
...
@@ -285,7 +266,8 @@ private:
void
setup_x_data
();
void
set_tilemap_x
();
void
add_next_road_pos
(
uint32_t
*
);
void
create_curve
();
void
create_curve
(
int16_t
&
,
int16_t
&
,
const
int32_t
,
const
int32_t
,
const
int16_t
,
const
int16_t
);
void
setup_hscroll
();
void
do_road_offset
(
int16_t
*
,
int16_t
,
bool
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment