REM *** Näyttötilan asettaminen *** screen_width% = 800 screen_height% = 600 MODE screen_width%, screen_height%, 32 REM *** Haetaan systeemikutsulla näyttömuistin alkuosoite *** DIM vdu% 15:!vdu% = 148:vdu%!4 = -1 SYS "OS_ReadVduVariables", vdu%, vdu%+8 REM *** Muuttujien alkuasetukset *** twister_height% = screen_height% twister_width% = 200 twister_radius% = twister_width% DIV 2 twister_xoffset% = screen_width% - twister_width% twister_num_angles% = 2048 DIV 4 rotation% = 0 : twistratiophase = 0 : framecount% = 0 starttime% = TIME REM *** Käännetään assembly-rutiini ajettavaksi koodiksi *** PROCassemble_draw_routine REM *** Lasketaan valmiiksi kaikkien pyörähdyskulmien arvot *** DIM twister_slices%(twister_num_angles%-1, 5) PROCprecalc_twister_slices REM *** Ohjelman pääsilmukka *** WHILE INKEY(0) = -1 twist = 0 twistratio = SIN(twistratiophase) * 1.2 REM Odotetaan kuvaruudun päivitystä eli "vsync" WAIT FOR Y% = 0 TO twister_height%-1 ang% = (rotation% + SIN(rotation% / 100) + twist) MOD twister_num_angles% twister_xoffset% = screen_width% DIV 2 + 100 * SIN(twistratiophase * 1.1 + twist * 0.0017) A% = vdu%!8 + (Y% * screen_width% + twister_xoffset%) * 4 B% = twister_slices%(ang%,0) + 6 C% = twister_slices%(ang%,1) D% = twister_slices%(ang%,2) E% = twister_slices%(ang%,3) F% = twister_slices%(ang%,4) G% = twister_slices%(ang%,5) + 6 H% = 0 CALL code% twist = twist + twistratio NEXT Y% rotation% = rotation% + 10 twistratiophase = twistratiophase + 0.014 framecount% = framecount% + 1 ENDWHILE endtime% = TIME PRINT (framecount%*100)/(endtime%-starttime%) " frames per second" REM *** Ohjelman loppu *** END REM ****** Aliohjelmat eli "rutiinit" ****** REM FNmax palauttaa luvuista f1 ja f2 suuremman. DEF FNmax(f1, f2) LOCAL result IF f1 > f2 THEN result = f1 ELSE result = f2 ENDIF =result REM FNmin palauttaa luvuista f1 ja f2 pienemmän. DEF FNmin(f1, f2) LOCAL result IF f1 < f2 THEN result = f1 ELSE result = f2 ENDIF =result REM *** Eri kääntökulmien arvojen laskenta taulukkoon valmiiksi *** DEF PROCprecalc_twister_slices LOCAL leftx%, midx%, rightx%, color1%, color2%, cr%, cg%, cb% LOCAL modangle, angle% LOCAL light1s1, light2s1, light3s1, light1s2, light2s2, light3s2 FOR angle% = 0 TO twister_num_angles% - 1 REM Välillä 3/4 PI .. 5/4 PI oleva kulma on aina vasemmanpuoleisin modangle = (angle% + 1.5 * twister_num_angles%) * PI / (twister_num_angles% * 2) REM Näkyvissä olevien kulmapisteiden x-koordinaatit leftx% = COS(modangle) * twister_radius% midx% = COS(modangle + PI / 2) * twister_radius% rightx% = COS(modangle + PI) * twister_radius% REM Näkyvien kahden sivun kirkkaudet kolmeen eri valovektoriin light1s1 = FNmax(-SIN(modangle + PI / 4 ), 0) light2s1 = FNmax(-SIN(modangle + PI / 4 - PI / 2 ), 0) light3s1 = FNmax(-SIN(modangle + PI / 4 + PI / 2 ), 0) light1s2 = FNmax(-SIN(modangle + 3 * PI / 4 ), 0) light2s2 = FNmax(-SIN(modangle + 3 * PI / 4 - PI / 2), 0) light3s2 = FNmax(-SIN(modangle + 3 * PI / 4 + PI / 2), 0) cr% = FNmin(light1s1 * 255 + light2s1 * 30, 255) cg% = (light1s1) * 255 cb% = FNmin(light1s1 * 255 + light3s1 * 30, 255) color1% = (cb% << 16) + (cg% << 8) + cr% cr% = FNmin(light1s2 * 255 + light2s2 * 30, 255) cg% = light1s2 * 255 cb% = FNmin(light1s2 * 255 + light3s2 * 30, 255) color2% = (cb% << 16) + (cg% << 8) + cr% twister_slices%(angle%, 0) = twister_radius%+leftx% twister_slices%(angle%, 1) = midx%-leftx% twister_slices%(angle%, 2) = color1% twister_slices%(angle%, 3) = rightx%-midx% twister_slices%(angle%, 4) = color2% twister_slices%(angle%, 5) = twister_radius%-rightx% NEXT angle% ENDPROC REM BASIC-rutiini, joka käännättää ARM-assembly-kielisen REM piirtorutiinin BASICin sisäänrakennetulla assemblerilla. DEF PROCassemble_draw_routine DIM code% 1000 FOR I% = 1 TO 3 STEP 2 CLS P% = code% [OPT I% ; Rekisterit ; r0 (A%) = piirron kohdeosoite ; r1 (B%) = vasemmanpuolisen mustan osan leveys ; r2 (C%) = vasemman sivun leveys ; r3 (D%) = vasemman sivun vari ; r4 (E%) = oikean sivun leveys ; r5 (F%) = oikean sivun vari ; r6 (G%) = oikeanpuolisen mustan osan leveys ; r7 (H%) = mustan eli taustavarin arvo cmp r1, #0 ble leftblackdone .leftblackloop str r7, [r0], #4 subs r1, r1, #1 bne leftblackloop .leftblackdone cmp r2, #0 ble leftsidedone .leftsideloop str r3, [r0], #4 subs r2, r2, #1 bne leftsideloop .leftsidedone cmp r4, #0 ble rightsidedone .rightsideloop str r5, [r0], #4 subs r4, r4, #1 bne rightsideloop .rightsidedone cmp r6, #0 ble rightblackdone .rightblackloop str r7, [r0], #4 subs r6, r6, #1 bne rightblackloop .rightblackdone mov r15, r14 ] NEXT I% ENDPROC