Skip to content

Test 2a: the dot in 3D

In test 1, the dot moved on a flat plane: left to right, and up and down. This test gives the world a third direction: depth. The dot still goes up and down with the sine. It now also moves from the back to the front. The curve starts far away and ends near you. Its middle point is the center of the 3D space. A near dot is larger, and a far dot comes nearer to the center of the screen.

A cassette tape with a handwritten label: "A Side. Assembly - the first language of the machine."

A What the machine does

The routines path_point and project, for the dot on the screen now.

    Waiting for the copy of the PC to start…

    Speed:

    Blue: the floor. Gray: the path in the air, from the back to the front. Cyan: the footprint of the path on the floor, a straight line through the center. The light-gray pole goes from the dot down to its shadow (red), so you can see where the dot is in the depth.

    A cassette tape with a handwritten label: "B Side. Fortran, the language that speaks maths."

    B The maths behind it

    The same point with decimal-point numbers, and two drawings of the world.

    From above: the eye, the screen and the dot
    screeneyefarnear
    From the side: the height and the depth
    eyescreenfloor: near … far

      What is new in test 2a

      1. B The same table. The laboratory (lab/sine_table.f90) makes no new file. The height of the dot is the sine, as in test 1.
      2. A A third direction. The routine path_point(src/path3d.inc) gives three numbers for each angle: X (left and right), Y (up and down, the sine), and Z (the depth: 128 at the back, down to -127 at the front). At the middle angle, 128, the point is X = 0, Y = 0, Z = 0: the center of the 3D space. Seen from above, the path is a straight line from the back left to the front right. Seen from the side, it is the sine curve.
      3. A The perspective. The routine project divides by the distance from the eye, with the 8086 word IDIV. A far point has a large distance, so it becomes small and goes to the center of the screen. The drawing "From above" shows why: the line from the eye to the dot crosses the screen at the screen x.
      4. A Signs of depth. The program (src/dot3d.asm) draws a floor, the footprint of the path, a pole from the dot to its shadow, and a larger dot when it is near. To remove the old dot, it keeps a list of the old colors of each pixel, and puts them back in reverse order.
      5. A B The check. The test (test/check3d.asm) runs the two routines for all 256 angles in DOSBox and writes three numbers for each: the screen x and y of the dot, and the screen y of its shadow. The checker (lab/check_3d.f90) calculates them again and compares them. If one number is different, GitHub Actions stops and does not publish the site.
      The two sides agree
      256 / 256
      points from the check (3 numbers each)
      Error from exact maths
      1 px
      the cost of whole-number arithmetic
      Size of the game
      1103 bytes
      DOT3D.COM, 8086 instructions only
      Size of the table
      512 bytes
      the same sine.bin as test 1

      The words that each program uses

      The pills show the words that the dictionary already has. "New words" are real words of the language that the dictionary does not have yet.

      A src/dot3d.asm· 222 lines · The game (test 2a): draws the floor and the path, and moves the dot in 3D

      42 dictionary words: MOVPUSHPOPAXBXCXDXSIDIBPES[ ]BYTEWORDDBDWEQUADDINCDECSHLSHRANDXORCMPJMPJE / JZJNE / JNZJB / JACALLRETlabel:ORGBITS%includeINCBIN;,hINTINT 10h, AX=0013hA000h

      New words (10): AHALBHBLCHCLCPUDLJGEJLE

      A src/path3d.inc· 81 lines · The shared routines: one angle in, one 3D point out, then one screen position

      22 dictionary words: MOVPUSHPOPAXBXCXDXSI[ ]EQUADDSUBIMULIDIVNEGSHLSHRSARRETlabel:;,

      New words (3): AHALDL

      A test/check3d.asm· 60 lines · The test: runs the routines for 256 angles and writes the positions to a file

      28 dictionary words: MOVPUSHPOPAXBXCXDXSIDI[ ]DBDWADDINCXORCMPJB / JACALLlabel:ORGBITS%includeTIMESINCBIN;,hINT

      New words (3): AHCPUJC

      B lab/sine_table.f90· 27 lines · The laboratory: makes the sine table (the same table as test 1)

      26 dictionary words: INTEGERREAL::=PARAMETERINT8 / INT16REAL64+ -* /( )SIN / COSNINTINT( )DOMAXVAL / MINVALPROGRAMENDUSEIMPLICIT NONE!PRINTWRITEOPENCLOSE'(F8.2)'ISO_FORTRAN_ENV

      New words (3): ACOSINTRINSICONLY

      B lab/check_3d.f90· 83 lines · The checker: compares the A-side positions with its own answers

      42 dictionary words: INTEGERREALCHARACTER::=PARAMETERINT8 / INT16REAL64+ -* /( )ABSSIN / COSNINTFLOORINT( )ISHFT / SHIFTAIF ... THEN ... END IFDOCYCLESTOPERROR STOPMERGE== /= < > <= >=MAXVAL / MINVALCOUNTANY / ALLPROGRAMENDUSEIMPLICIT NONECALL!&PRINTWRITEREADOPENCLOSEGET_COMMAND_ARGUMENT'(F8.2)'ISO_FORTRAN_ENV

      New words (7): ACOSCOMMAND_ARGUMENT_COUNTDIMINTRINSICLENONLYTRIM

      Next: test 2b runs this program with one wrong word, and shows how the check finds the error. The copy of the PC is js-dos 8.4.1, the same as on thetest 1 page.