module "/pliant/language/context.pli"
module "/pliant/math/functions.pli"
module "/pliant/SDL/SDL.pli"
type MODE7_PARAMS
field Float space_z
field Int horizon
field Float scale_x scale_y
function mode7 image texture angle cx cy params
arg Pointer:SDL_Surface image texture
arg Float angle cx cy
arg MODE7_PARAMS params
var Address image_p texture_p
var Int screen_x screen_y
var Float distance horizontal_scale
var Int mask_x := texture:w - 1
var Int mask_y := texture:h - 1
var Int mx my offset
var Float line_dx line_dy
var Float space_x space_y
image_p := image:pixels
texture_p := texture:pixels
for screen_y 0 (image:h-1) step 2
distance := (params:space_z * params:scale_y) / (screen_y + params:horizon)
horizontal_scale := distance / params:scale_x
line_dx := -1 * (sin angle)* horizontal_scale
line_dy := (cos angle) * horizontal_scale
space_x := cx + (distance * (cos angle)) - ((image:w / 2) * line_dx)
space_y := cy + (distance * (sin angle)) - ((image:h / 2) * line_dy)
for screen_x 0 (image:w-1)
mx := ((cast space_x Int)) .and. mask_x
my := ((cast space_y Int)) .and. mask_y
offset := my * texture:pitch + mx
(image_p map uInt8) := (texture_p map uInt8 offset)
image_p := (image_p translate uInt8 1)
space_x += line_dx
space_y += line_dy
image_p := (image_p translate uInt8 image:pitch)
function main
var Pointer:SDL_Surface screen texture
var MODE7_PARAMS sp
var Float angle offset_x offset_y
var SDL_Event event
var Int keydown := 0
var Float turn := 0.0
var Float altitude := 0.0
sp:space_z := 512.0
sp:horizon := 10
sp:scale_x := 512.0
sp:scale_y := 512.0
if (SDL_Init SDL_INIT_VIDEO) < 0
console "could not init video!" eol
SDL_QUIT
return
screen :> SDL_SetVideoMode 640 480 8 0
if not (exists screen)
console "Could not open display." eol
SDL_Quit
return
texture :> SDL_LoadBMP "astro_bright.bmp"
if not (exists texture)
console "Could not load astro.bmp" eol
SDL_Quit
return
SDL_SetColors screen texture:format:palette:colors 0 texture:format:palette:ncolors
angle := 0.0
var CBool done := false
while not done
while (SDL_PollEvent:event > 0)
if event:type = SDL_QUIT
done := true
eif event:type = SDL_KEYDOWN
keydown := event:key:keysym:sym
eif event:type = SDL_KEYUP
keydown := 0
if keydown = SDLK_LEFT
turn += 0.05
eif keydown = SDLK_RIGHT
turn -= 0.05
eif keydown = SDLK_UP and altitude < 400.0
altitude += 4.0
sp:horizon += 1
eif keydown = SDLK_DOWN and altitude > 0.0
altitude -= 4.0
sp:horizon -= 1
eif keydown = SDLK_ESCAPE
done := true
sp:space_z := 50 + altitude
SDL_LockSurface screen
(mode7 screen texture turn 50*angle (sin angle/4)*50.0 sp)
SDL_UnlockSurface screen
SDL_UpdateRect screen 0 0 0 0
angle += 0.1
SDL_FreeSurface texture
SDL_Quit
return
main