Home | Contents | KwikPik |
Issue 19 | "Check It Out ..." |
3 D | D A Z E | ||||||||
---|---|---|---|---|---|---|---|---|---|
It's here - the ultimate in 3D graphics. Mr MegaBasic, Mike Leaman shows another side to his talents with a program that'll transport you into the third dimension. | |||||||||
How often have you wished you could create the smooth three dimensional graphics like the ones Ultimate has made famous in Knight Lore and Alien 8? Well, now you can - almost. Of course, the Ultimate team doesn't actually program on the Spectrum but on a much larger machine, then squirts it down. But you can get pretty close with these machine code routines that'll enable |
you to move objects in three dimensions.
The tricky bit about 3D graphics is making sure that the objects meant to be at the front of the display look as though that's where they are. So, how's it done? Well, briefly, you have to draw the objects at the back first and then work your way forward. I've tackled it by keeping a list of all the objects that appear on the screen and this | list contracts and expands according to how many objects there are. The list starts at 64700 and each entry consists of four bytes. Understanding these is the tricky bit. The first byte is the 'X' co-ordinate, the second the 'Y'-co-ordinate, the third the 'Z' co-ordinate and the last byte is the objects' code number. The easiest way to understand these co-ordinates is to think in terms |
of a matchbox - hold it up in front of you. 'Y' runs along the bottom from left to right, 'X' runs up the edge that goes from the top to bottom and 'Z' is the co-ordinate that travels along the edge that's going away from you. If you're still in trouble or you want to go into further depth, take a look at the articles on 3D plotting in YS issues 2 and 3.
Now back to that list. Those objects that are to be placed at the back come at the start of the list. Then each time an object is displayed or erased, the list is scanned and the appropriate action taken. The shape of each object is stored in 64 bytes of RAM and I've included three objects with the code. The shape list starts at 65047, so that's where you'll find the first object, then the second object is at 65047+64 and so on. The 64 bytes of character info is split into two halves - the first 32 bytes represent the actual shape of the object, similar to the way you would define a UDG but with much more information because of the third dimension. This is followed by the second 32 byte block that describes the shape of the mask needed to erase the object. Now take a look at the code. It's in two parts - the first part that does all the work starts at 64000 and the second part contains shape info for the three example objects and starts at 65047. Here's how you enter the code. First type in the Hex loader and save it - you may need it later. Now RUN it and it'll automatically lower RAMtop so that there's space for the code. You'll then be asked for a start address - for the main block, enter 64000 and for the shape info enter 65047. Once you've put those in, you can press on with entering the actual code. For starters, you'l1 be prompted with an | ||||||
|
address - look at the main listing - the first prompt'll be 64000 so you should enter F3. The second prompt is 64001, so you'll enter CD93FB, remembering, of course, not to enter any spaces.
When you've reached the end of a block, enter 'S' - the loader will then ask you for a Checksum. For the main block enter 79933, then for the shape data enter 17774. Now the loader checks the code for errors. If it finds one you'll just have to go back and re-check. As soon as you've entered the main block, carry on and enter the shape data and then save the code using: SAVE "code" CODE 64000,1368 Now enter NEW and type in the test program, again remembering to save it just in |
case the code crashes. At last, you're there! If all's well, you should be greeted by a number of bubbles moving across the screen in full and glorious 3D.
OK, I can already hear you asking how you can use the routines yourself. As I've said, it takes four parameters to describe an object - the 'X', `Y' and 'Z' co-ordinates plus the shape code that defines what shape the object is to take. These parameters are passed to the machine code in four locations: 64637 'Y' co-ordinate 64638 'X' co-ordinate 64639 shape code 64640 'Z' co-ordinate Well, there are three routines that you can usefully adapt. The first is the one that covers the background. |
To understand this, you must know that the middle third of the screen is printed first, so you can use this part as a back drop. So, design your
back drop and save it into memory which you can do as follows: first, reserve an area of memory using the CLEAR command, then POKE the address of this area into locations 64635 and 64636. Once you've drawn your backdrop, call the routine at 64423 and this'll save the middle third of the screen into memory.
Now to print an object POKE its co-ordinates into the correct memory locations and call the routine at 64489. Then to erase an object POKE its co-ordinates into the correct locations and call the routine at 64556. You'll also have to remember to execute POKE 64703,0 before you start printing - that |
way you'll clear the display list. And finally a word of warning - so that the routine's as fast as possible I've left out all the error checking. You'll have to make sure that none of your 3D objects goes wandering off the edge of the screen or you may find yourself with a system crash.
And now onto next month [see The 3D 3]. Watch out for a 3D graphic designer that'll let you create your own clockwork mice or mutant daleks. Plus, for all the clever people who've mastered YS MegaBasic, I'll be showing you how to convert this month's machine code into MegaBasic. All you'll have to use then are a number of new Basic commands. Of course, all you poor socially deprived Speccy owners still relying on Sinclair Basic will have to resort to the infamous commands POKE and USR. It's a tough life! |
A NEW DIMENSION |
Use this hex loader to enter the hex code from both the character info and the main assembler listing. |
10 CLEAR 63999 15 POKE 23658,8 17 DEF FN h(h$)=16*(CODE (h$)-48-7*(h$(1)>"9"))+(CODE (h$(2))-48-7*(h$(2)>"9")) 20 INPUT "Start address ";a 25 LET z=a 30 INPUT (a), LINE a$ 35 IF a$="S" THEN GO TO 90 40 PRINT a,a$: POKE 23692,255 50 FOR z=1 TO LEN a$/2 60 POKE a,FN h(a$(((z*2)-1) TO )): LET a=a+1 70 NEXT z 80 GO TO 30 90 INPUT "Checksum ";d 100 LET c=0: FOR b=z TO a-1: LET c=c+PEEK b: NEXT b 110 IF c=d THEN PRINT "The code is OK!": STOP 120 PRINT "Oh dear, the code is incorrect": STOP |
This is reproduced as it was printed in the magazine - including the error. The variable Z assigned at line 25 is also used in the loop in lines 50-70, so its value gets overwritten. Change the references to Z in the loop to some other letter. |
ASSEMBLER 3-DUMP | |||
This is the main assembler listing, which you can either type in using an assembler, monitor or our own Hex loader. | |||
64000 F3 DI 64001 CD93FB CALL 64403 64004 DD21BCFC LD IX,64700 64008 DD7E03 LD A,(IX+003) 64011 A7 AND A 64012 281E JR Z,64044 64014 CD32FA CALL 64050 64017 AF XOR A 64018 DD6E00 LD L,(IX+000) 64021 DD6601 LD H,(IX+001) 64024 DD5602 LD D,(IX+002) 64027 DD23 INC IX 64029 DD23 INC IX 64031 DD23 INC IX 64033 DD23 INC IX 64035 DDE5 PUSH IX 64037 CD6BFA CALL 64107 64040 DDE1 POP IX 64042 18DC JR 64008 64044 FD213A5C LD IY,23610 64048 FB EI 64049 C9 RET 64050 3D DEC A 64051 2600 LD H,000 64053 6F LD L,A 64054 29 ADD HL,HL 64055 29 ADD HL,HL 64056 29 ADD HL,HL 64057 29 ADD HL,HL 64058 29 ADD HL,HL 64059 29 ADD HL,HL 64060 0117FE LD BC,65047 64063 09 ADD HL,BC 64064 44 LD B,H 64065 4D LD C,L 64066 C9 RET 64067 3EBF LD A,191 64069 90 SUB B 64070 47 LD B,A 64071 210040 LD HL,16384 64074 78 LD A,B 64075 E6C0 AND 192 64077 1E00 LD E,000 64079 57 LD D,A 64080 CB3A SRL D 64082 CB3A SRL D 64084 CB3A SRL D 64086 19 ADD HL,DE 64087 78 LD A,B 64088 E607 AND 007 64090 84 ADD A,H 64091 67 LD H,A 64092 78 LD A,B 64093 E638 AND 056 64095 CB27 SLA A 64097 CB27 SLA A 64099 5F LD E,A 64100 1600 LD D,000 64102 19 ADD HL,DE 64103 0600 LD B,000 64105 09 ADD HL,BC 64106 C9 RET 64107 328BFB LD (64395),A 64110 E5 PUSH HL 64111 C5 PUSH BC 64112 DDE1 POP IX 64114 212000 LD HL,00032 64117 09 ADD HL,BC 64118 E5 PUSH HL 64119 FDE1 POP IY 64121 E1 POP HL 64122 CD6BFB CALL 64363 64125 F5 PUSH AF 64126 CD47FB CALL 64327 64129 C1 POP BC 64130 4F LD C,A 64131 E607 AND 007 64133 328CFB LD (64396),A 64136 6F LD L,A 64137 2600 LD H,000 64139 29 ADD HL,HL 64140 29 ADD HL,HL 64141 29 ADD HL,HL 64142 C5 PUSH BC 64143 010EFB LD BC,64270 64146 09 ADD HL,BC 64147 C1 POP BC 64148 36C9 LD (HL),201 64150 2291FB LD (64401),HL 64153 79 LD A,C | 64154 CB3F SRL A 64156 CB3F SRL A 64158 CB3F SRL A 64160 4F LD C,A 64161 328DFB LD (64397),A 64164 78 LD A,B 64165 328EFB LD (64398),A 64168 CD43FA CALL 64067 64171 0610 LD B,016 64173 3A8EFB LD A,(64398) 64176 C5 PUSH BC 64177 E607 AND 007 64179 FE07 CP 007 64181 2007 JR NZ,64190 64183 ED4B8DFB LD BC,(64397) 64187 CD43FA CALL 64067 64190 FD4600 LD B,(IY+000) 64193 FD4E01 LD C,(IY+001) 64196 16FF LD D,255 64198 CD0DFB CALL 64269 64201 E5 PUSH HL 64202 7E LD A,(HL) 64203 A0 AND B 64204 77 LD (HL),A 64205 23 INC HL 64206 7E LD A,(HL) 64207 A1 AND C 64208 77 LD (HL),A 64209 23 INC HL 64210 7E LD A,(HL) 64211 A2 AND D 64212 77 LD (HL),A 64213 FD23 INC IY 64215 FD23 INC IY 64217 E1 POP HL 64218 3A8BFB LD A,(64395) 64221 A7 AND A 64222 201C JR NZ,64252 64224 E5 PUSH HL 64225 DD4600 LD B,(IX+000) 64228 DD4E01 LD C,(IX+001) 64231 1600 LD D,000 64233 CD0DFB CALL 64269 64236 78 LD A,B 64237 B6 OR (HL) 64238 77 LD (HL),A 64239 23 INC HL 64240 79 LD A,C 64241 B6 OR (HL) 64242 77 LD (HL),A 64243 23 INC HL 64244 7A LD A,D 64245 B6 OR (HL) 64246 77 LD (HL),A 64247 DD23 INC IX 64249 DD23 INC IX 64251 E1 POP HL 64252 3A8EFB LD A,(64398) 64255 3D DEC A 64256 328EFB LD (64398),A 64259 24 INC H 64260 C1 POP BC 64261 10A9 DJNZ 64176 64263 2A91FB LD HL,(64401) 64266 36CB LD (HL),203 64268 C9 RET 64269 5A LD E,D 64270 CB3B SRL E 64272 CB18 RR B 64274 CB19 RR C 64276 CB1A RR D 64278 CB3B SRL E 64280 CB18 RR B 64282 CB19 RR C 64284 CB1A RR D 64286 CB3B SRL E 64288 CB18 RR B 64290 CB19 RR C 64292 CB1A RR D 64294 CB3B SRL E 64296 CB18 RR B 64298 CB19 RR C 64300 CB1A RR D 64302 CB3B SRL E 64304 CB18 RR B 64306 CB19 RR C 64308 CB1A RR D 64310 CB3B SRL E 64312 CB18 RR B 64314 CB19 RR C | 64316 CB1A RR D 64318 CB3B SRL E 64320 CB18 RR B 64322 CB19 RR C 64324 CB1A RR D 64326 C9 RET 64327 C5 PUSH BC 64328 D5 PUSH DE 64329 E5 PUSH HL 64330 5C LD E,H 64331 2600 LD H,000 64333 E5 PUSH HL 64334 29 ADD HL,HL 64335 C1 POP BC 64336 09 ADD HL,BC 64337 CB3C SRL H 64339 CB1D RR L 64341 CB3C SRL H 64343 CB1D RR L 64345 CB3B SRL E 64347 7D LD A,L 64348 83 ADD A,E 64349 F5 PUSH AF 64350 CB3F SRL A 64352 E1 POP HL 64353 84 ADD A,H 64354 67 LD H,A 64355 3A8FFB LD A,(64399) 64358 84 ADD A,H 64359 E1 POP HL 64360 D1 POP DE 64361 C1 POP BC 64362 C9 RET 64363 C5 PUSH BC 64364 D5 PUSH DE 64365 E5 PUSH HL 64366 5C LD E,H 64367 2600 LD H,000 64369 E5 PUSH HL 64370 29 ADD HL,HL 64371 C1 POP BC 64372 09 ADD HL,BC 64373 CB3C SRL H 64375 CB1D RR L 64377 CB3C SRL H 64379 CB1D RR L 64381 CB3B SRL E 64383 7D LD A,L 64384 93 SUB E 64385 82 ADD A,D 64386 67 LD H,A 64387 3A90FB LD A,(64400) 64390 84 ADD A,H 64391 E1 POP HL 64392 D1 POP DE 64393 C1 POP BC 64394 C9 RET 64395**00 00 00 00 64399**00 28 00 00 64403 2A7BFC LD HL,(64635) 64406 110048 LD DE,18432 64409 010008 LD BC,02048 64412 1A LD A,(DE) 64413 B6 OR (HL) 64414 12 LD (DE),A 64415 13 INC DE 64416 23 INC HL 64417 0B DEC BC 64418 78 LD A,B 64419 B1 OR C 64420 20F6 JR NZ,64412 64422 C9 RET 64423 ED5B7BFC LD DE,(64635) 64427 210048 LD HL,18432 64430 010008 LD BC,02048 64433 EDB0 LDIR 64435 C9 RET 64436 DD21BCFC LD IX,64700 64440 DD7E03 LD A,(IX+003) 64443 A7 AND A 64444 C8 RET Z 64445 DD7E01 LD A,(IX+001) 64448 B9 CP C 64449 280B JR Z,64462 64451 D0 RET NC 64452 DD23 INC IX 64454 DD23 INC IX 64456 DD23 INC IX 64458 DD23 INC IX | 64460 18EA JR 64440 64462 DD7E00 LD A,(IX+000) 64465 B8 CP B 64466 2804 JR Z,64472 64468 300A JR NC,64480 64470 18EC JR 64452 64472 DD7E02 LD A,(IX+002) 64475 BA CP D 64476 3002 JR NC,64480 64478 18E4 JR 64452 64480 DD23 INC IX 64482 DD23 INC IX 64484 DD23 INC IX 64486 DD23 INC IX 64488 C9 RET 64489 ED4B7DFC LD BC,(64637) 64493 ED5B7FFC LD DE,(64639) 64497 C5 PUSH BC 64498 D5 PUSH DE 64499 CDB4FB CALL 64436 64502 DDE5 PUSH IX 64504 D1 POP DE 64505 212FFD LD HL,64815 64508 E5 PUSH HL 64509 A7 AND A 64510 ED52 SBC HL,DE 64512 44 LD B,H 64513 4D LD C,L 64514 1133FD LD DE,64819 64517 E1 POP HL 64518 03 INC BC 64519 EDB8 LDDR 64521 D1 POP DE 64522 C1 POP BC 64523 DD7000 LD (IX+000),B 64526 DD7101 LD (IX+001),C 64529 DD7202 LD (IX+002),D 64532 3A7FFC LD A,(64639) 64535 DD7703 LD (IX+003),A 64538 AF XOR A 64539 3233FD LD (64819),A 64542 CD00FA CALL 64000 64545 C9 RET 64546 ED4B7DFC LD BC,(64637) 64550 ED5B7FFC LD DE,(64639) 64554 DD21BCFC LD IX,64700 64558 DD7E03 LD A,(IX+003) 64561 A7 AND A 64562 C8 RET Z 64563 78 LD A,B 64564 DDBE00 CP (IX+000) 64567 200C JR NZ,64581 64569 79 LD A,C 64570 DDBE01 CP (IX+001) 64573 2006 JR NZ,64581 64575 7A LD A,D 64576 DDBE02 CP (IX+002) 64579 280A JR Z,64591 64581 DD23 INC IX 64583 DD23 INC IX 64585 DD23 INC IX 64587 DD23 INC IX 64589 18DF JR 64558 64591 DD7E03 LD A,(IX+003) 64594 CD32FA CALL 64050 64597 C5 PUSH BC 64598 212FFD LD HL,64815 64601 DDE5 PUSH IX 64603 D1 POP DE 64604 ED52 SBC HL,DE 64606 44 LD B,H 64607 4D LD C,L 64608 62 LD H,D 64609 6B LD L,E 64610 23 INC HL 64611 23 INC HL 64612 23 INC HL 64613 23 INC HL 64614 EDB0 LDIR 64616 C1 POP BC 64617 3A7DFC LD A,(64637) 64620 67 LD H,A 64621 3A7EFC LD A,(64638) 64624 6F LD L,A 64625 3A80FC LD A,(64640) 64628 57 LD D,A 64629 3E01 LD A,001 64631 CD6BFA CALL 64107 64634 C9 RET 64635**00 48 00 00 64639**00 00 64641 00 NOP |
CHARACTER INFORMATION | ||
This is the character info used by the main listing for the graphics displayed in 3D. These are stored in 64 bytes, 32 bytes for the shape and another 32 for the mask. | ||
65047**03 C0 0C 30 65051**10 08 27 04 65055**2A 04 4C 02 65059**40 02 40 02 65063**40 02 20 04 65067**20 04 10 08 65071**0C 30 03 C0 65075**00 00 00 00 65079**FC 3F F0 0F 65083**E0 07 C0 03 65087**C0 03 80 01 65091**80 01 80 01 65095**80 01 C0 03 65099**C0 03 E0 07 65103**F0 0F FC 3F 65107**FF FF FF FF | 65111**00 80 01 C0 65115**01 A0 02 90 65119**04 88 08 84 65123**09 02 11 01 65127**21 06 31 18 65131**0F 60 01 80 65135**00 00 00 00 65139**00 00 00 00 65143**FF 7F FE 3F 65147**FE 1F FC 0F 65151**F8 07 F0 03 65155**F0 01 E0 00 65159**C0 01 C0 07 65163**F0 1F FE 7F 65167**FF FF FF FF 65171**FF FF FF FF | 65175**00 00 07 F0 65179**08 08 10 04 65183**17 74 13 64 65187**10 04 12 A4 65191**15 54 10 04 65195**10 04 1F FC 65199**15 54 00 00 65203**00 00 00 00 65207**FF FF F8 0F 65211**F0 07 E0 03 65215**E0 03 E0 03 65219**E0 03 E0 03 65223**E0 03 E0 03 65227**E0 03 E0 03 65231**EA AB FF FF 65235**FF FF FF FF |
THREE D-EMONSTRATION |
Once you've entered all the code, here's the program that'll give you the moving picture show. Just type it in and then RUN it. Back row of the stalls, please. |
10 BORDER 0: PAPER 0: INK 6: CLEAR 63999 20 POKE 64703,0 30 FOR y=0 TO 30 STEP 10 40 POKE 64637,y: POKE 64638,0: POKE 64639,1: POKE 64640,0 50 LET print=USR 64489 60 NEXT y 70 FOR y=0 TO 30 STEP 10 80 FOR x=0 TO 162 STEP 3 90 POKE 64637,y: POKE 64638,x 100 LET erase=USR 64546 110 POKE 64638,x+3: LET print=USR 64489 115 PAUSE 2 120 NEXT x 130 NEXT y 140 FOR y=0 TO 30 STEP 10 150 FOR x=165 TO 3 STEP -3 160 POKE 64637,y: POKE 64638,x 170 LET erase=USR 64546 180 POKE 64638,x-3: LET print=USR 64489 185 PAUSE 2 190 NEXT x: NEXT y 200 GO TO 70 |
Home | Contents | KwikPik |