Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
Anders Mundt Due
OneLoneCoder
Commits
68f774e3
Unverified
Commit
68f774e3
authored
Apr 15, 2018
by
Javidx9
Committed by
GitHub
Apr 15, 2018
Browse files
Added Mode7 Video
parent
56b99460
Changes
3
Hide whitespace changes
Inline
Side-by-side
OneLoneCoder_Pseudo3DPlanesMode7.cpp
0 → 100644
View file @
68f774e3
/*
OneLoneCoder.com - Programming Pseudo 3D planes, aka MODE7
"The SNES was too advanced for its time" - @Javidx9
License
~~~~~~~
Copyright (C) 2018 Javidx9
This program comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to redistribute it
under certain conditions; See license for details.
Original works located at:
https://www.github.com/onelonecoder
https://www.onelonecoder.com
https://www.youtube.com/javidx9
GNU GPLv3
https://github.com/OneLoneCoder/videos/blob/master/LICENSE
From Javidx9 :)
~~~~~~~~~~~~~~~
Hello! Ultimately I don't care what you use this for. It's intended to be
educational, and perhaps to the oddly minded - a little bit of fun.
Please hack this, change it and use it in any way you see fit. You acknowledge
that I am not responsible for anything bad that happens as a result of
your actions. However this code is protected by GNU GPLv3, see the license in the
github repo. This means you must attribute me if you use it. You can view this
license here: https://github.com/OneLoneCoder/videos/blob/master/LICENSE
Cheers!
Background
~~~~~~~~~~
Pseudo 3D was a technique made popular by the Super Nintendo
in games such as Super Mario Kart. This code demonstrates the
effect of that hardware mode.
Author
~~~~~~
Twitter: @javidx9
Blog: www.onelonecoder.com
Video:
~~~~~~
https://youtu.be/ybLZyY655iY
Last Updated: 15/04/2018
*/
#include
"olcConsoleGameEngine.h"
class
OneLoneCoder_FakeMode7
:
public
olcConsoleGameEngine
{
public:
OneLoneCoder_FakeMode7
()
{
m_sAppName
=
L"Pseudo 3D Planes"
;
}
private:
float
fWorldX
=
1000.0
f
;
float
fWorldY
=
1000.0
f
;
float
fWorldA
=
0.1
f
;
float
fNear
=
0.005
f
;
float
fFar
=
0.03
f
;
float
fFoVHalf
=
3.14159
f
/
4.0
f
;
olcSprite
*
sprGround
;
olcSprite
*
sprSky
;
int
nMapSize
=
1024
;
protected:
virtual
bool
OnUserCreate
()
{
// Create a large sprite and fill it with horizontal and vertical lines
//sprGround = new olcSprite(nMapSize, nMapSize);
//for (int x = 0; x <= nMapSize; x += 32)
//{
// for (int y = 0; y < nMapSize; y++)
// {
// sprGround->SetColour(x, y, FG_MAGENTA);
// sprGround->SetGlyph(x, y, PIXEL_SOLID);
// sprGround->SetColour(x+1, y, FG_MAGENTA);
// sprGround->SetGlyph(x+1, y, PIXEL_SOLID);
// sprGround->SetColour(x-1, y, FG_MAGENTA);
// sprGround->SetGlyph(x-1, y, PIXEL_SOLID);
// sprGround->SetColour(y, x, FG_BLUE);
// sprGround->SetGlyph(y, x, PIXEL_SOLID);
// sprGround->SetColour(y, x+1, FG_BLUE);
// sprGround->SetGlyph(y, x+1, PIXEL_SOLID);
// sprGround->SetColour(y, x-1, FG_BLUE);
// sprGround->SetGlyph(y, x-1, PIXEL_SOLID);
// }
//}
// Simply load very large sprites from file
sprGround
=
new
olcSprite
(
L"mariokart.spr"
);
sprSky
=
new
olcSprite
(
L"sky1.spr"
);
return
true
;
}
virtual
bool
OnUserUpdate
(
float
fElapsedTime
)
{
// Control rendering parameters dynamically
if
(
GetKey
(
L'Q'
).
bHeld
)
fNear
+=
0.1
f
*
fElapsedTime
;
if
(
GetKey
(
L'A'
).
bHeld
)
fNear
-=
0.1
f
*
fElapsedTime
;
if
(
GetKey
(
L'W'
).
bHeld
)
fFar
+=
0.1
f
*
fElapsedTime
;
if
(
GetKey
(
L'S'
).
bHeld
)
fFar
-=
0.1
f
*
fElapsedTime
;
if
(
GetKey
(
L'Z'
).
bHeld
)
fFoVHalf
+=
0.1
f
*
fElapsedTime
;
if
(
GetKey
(
L'X'
).
bHeld
)
fFoVHalf
-=
0.1
f
*
fElapsedTime
;
// Create Frustum corner points
float
fFarX1
=
fWorldX
+
cosf
(
fWorldA
-
fFoVHalf
)
*
fFar
;
float
fFarY1
=
fWorldY
+
sinf
(
fWorldA
-
fFoVHalf
)
*
fFar
;
float
fNearX1
=
fWorldX
+
cosf
(
fWorldA
-
fFoVHalf
)
*
fNear
;
float
fNearY1
=
fWorldY
+
sinf
(
fWorldA
-
fFoVHalf
)
*
fNear
;
float
fFarX2
=
fWorldX
+
cosf
(
fWorldA
+
fFoVHalf
)
*
fFar
;
float
fFarY2
=
fWorldY
+
sinf
(
fWorldA
+
fFoVHalf
)
*
fFar
;
float
fNearX2
=
fWorldX
+
cosf
(
fWorldA
+
fFoVHalf
)
*
fNear
;
float
fNearY2
=
fWorldY
+
sinf
(
fWorldA
+
fFoVHalf
)
*
fNear
;
// Starting with furthest away line and work towards the camera point
for
(
int
y
=
0
;
y
<
ScreenHeight
()
/
2
;
y
++
)
{
// Take a sample point for depth linearly related to rows down screen
float
fSampleDepth
=
(
float
)
y
/
((
float
)
ScreenHeight
()
/
2.0
f
);
// Use sample point in non-linear (1/x) way to enable perspective
// and grab start and end points for lines across the screen
float
fStartX
=
(
fFarX1
-
fNearX1
)
/
(
fSampleDepth
)
+
fNearX1
;
float
fStartY
=
(
fFarY1
-
fNearY1
)
/
(
fSampleDepth
)
+
fNearY1
;
float
fEndX
=
(
fFarX2
-
fNearX2
)
/
(
fSampleDepth
)
+
fNearX2
;
float
fEndY
=
(
fFarY2
-
fNearY2
)
/
(
fSampleDepth
)
+
fNearY2
;
// Linearly interpolate lines across the screen
for
(
int
x
=
0
;
x
<
ScreenWidth
();
x
++
)
{
float
fSampleWidth
=
(
float
)
x
/
(
float
)
ScreenWidth
();
float
fSampleX
=
(
fEndX
-
fStartX
)
*
fSampleWidth
+
fStartX
;
float
fSampleY
=
(
fEndY
-
fStartY
)
*
fSampleWidth
+
fStartY
;
// Wrap sample coordinates to give "infinite" periodicity on maps
fSampleX
=
fmod
(
fSampleX
,
1.0
f
);
fSampleY
=
fmod
(
fSampleY
,
1.0
f
);
// Sample symbol and colour from map sprite, and draw the
// pixel to the screen
wchar_t
sym
=
sprGround
->
SampleGlyph
(
fSampleX
,
fSampleY
);
short
col
=
sprGround
->
SampleColour
(
fSampleX
,
fSampleY
);
Draw
(
x
,
y
+
(
ScreenHeight
()
/
2
),
sym
,
col
);
// Sample symbol and colour from sky sprite, we can use same
// coordinates, but we need to draw the "inverted" y-location
sym
=
sprSky
->
SampleGlyph
(
fSampleX
,
fSampleY
);
col
=
sprSky
->
SampleColour
(
fSampleX
,
fSampleY
);
Draw
(
x
,
(
ScreenHeight
()
/
2
)
-
y
,
sym
,
col
);
}
}
// Draw a blanking line to fill the gap between sky and ground
DrawLine
(
0
,
ScreenHeight
()
/
2
,
ScreenWidth
(),
ScreenHeight
()
/
2
,
PIXEL_SOLID
,
FG_CYAN
);
// Handle user navigation with arrow keys
if
(
GetKey
(
VK_LEFT
).
bHeld
)
fWorldA
-=
1.0
f
*
fElapsedTime
;
if
(
GetKey
(
VK_RIGHT
).
bHeld
)
fWorldA
+=
1.0
f
*
fElapsedTime
;
if
(
GetKey
(
VK_UP
).
bHeld
)
{
fWorldX
+=
cosf
(
fWorldA
)
*
0.2
f
*
fElapsedTime
;
fWorldY
+=
sinf
(
fWorldA
)
*
0.2
f
*
fElapsedTime
;
}
if
(
GetKey
(
VK_DOWN
).
bHeld
)
{
fWorldX
-=
cosf
(
fWorldA
)
*
0.2
f
*
fElapsedTime
;
fWorldY
-=
sinf
(
fWorldA
)
*
0.2
f
*
fElapsedTime
;
}
return
true
;
}
};
int
main
()
{
OneLoneCoder_FakeMode7
game
;
game
.
ConstructConsole
(
320
,
240
,
4
,
4
);
game
.
Start
();
return
0
;
}
\ No newline at end of file
mariokart.spr
0 → 100644
View file @
68f774e3
File added
sky1.spr
0 → 100644
View file @
68f774e3
File added
Write
Preview
Supports
Markdown
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