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