Out of boredom I started ghidra and started to disassemble Elite to see if we could get the full shipset in there.
Elite draws its graphics mainly in a background bitmap at address 0xa000 to 0xc000 and then copies it to the screenmemory at 0xc000, so banking should be possible. After several hours, proof-of-concept for a 128k version is achieved.
Thanks to banking, it has now been possible to free up space for the ships' data storage in the invisible program code, which is stored in the image memory,
The routines stored in the image memory are now, enriched with the ship definitions and the character set, stored in bank C9 and graphics routines are patched in such a way that they activate the image memory again when something is to be displayed. *)
There was also room in the program code itself, as the table with the ship's data was moved to the banked area and a routine that transferred the character set from the ROM to the hidden screen area could also be thrown out.
I was able to find graphic data for the ships in dissassembled versions for the Apple and C64, unfortunately the information in the headers and from the edges and faces differ and I have not yet been able to get Elite to display one of the newly added models because the purpose of some of the data in the headers is unknown. In the versions for the 6052s, the header is 20 bytes; at the CPC (and probably also Speccy) 23 bytes. Part of the data is identical, but is in different places.
The basic idea of the whole thing is, since Elite is a Speccy port, to compare the codes with each other and then to compare the codes with the Russian extension and possibly port them ....
Unfortunately, I am not familiar with the spectrum at all and have no ideas how I can get the binary files from TAP files or disk images and would be very grateful if someone could send me the bin files with load addresses
*) The routines for the text screens have successfully evaded treatment for several hours and you sat in front of a screen and wondered why nothing happened after the second splash screen and it looked as if the program was hanging before i found out, that bankswitching of the routine was wrong and the text was drawn on the wrong bank.
OMG - this is fantastic. Elite on the CPC was the game I spent most time with in my whole life. Although I only reached "deadly" status.
So, I hope you are still bored for a few more sessions ;-) and I will definitely give this a try once it's playable.
@Fessor (https://www.cpcwiki.eu/forum/index.php?action=profile;u=1495)
@reidrac (https://www.cpcwiki.eu/forum/index.php?action=profile;u=1504) is familar with both systems, maybe he can offer some support.
This is a very exciting project!
I'm wondering, if you're changing it from a screen buffer copy method to banking, is there a small speed-up?
Very cool. But since you now have more memory, maybe revamp the game a bit more and add, for example, music? Like "battle" music when enemies are encountered, "docking" music, "station" music, etc. Could be interesting. But that implies being able to detect such situation, which may not be so easy.
Can you share all the ship header + data from the BBC and the CPC versions? Maybe some group investigation will find a solution.
Wasn't the BBC Micro source code for Elite released long time ago from Ian Bell ?
Quote from: SkulleateR on 12:52, 22 July 21
Wasn't the BBC Micro source code for Elite released long time ago from Ian Bell ?
yes: http://www.elitehomepage.org/archive/index.htm
Quote from: eto on 13:02, 22 July 21
yes: http://www.elitehomepage.org/archive/index.htm (http://www.elitehomepage.org/archive/index.htm)
Even better, the source code has also been fully documented here: https://github.com/markmoxon/cassette-elite-beebasm (https://github.com/markmoxon/cassette-elite-beebasm)
See this thread over on stardot too: https://stardot.org.uk/forums/viewtopic.php?t=20377 (https://stardot.org.uk/forums/viewtopic.php?t=20377)
Finding disassemblies for the 6502s is no problem. I use the code from the Apple version https://6502disassembly.com/a2-elite/Elite.html#SymMVEIT , and everything is pretty well documented there and also the c-source of Elite TNK to understand the flow of the Program.. They all profit from the published source code for the BBC. (Dont know if it would be possible to use the c-source with sdcc)
But you can't find anything for the Z80. I have expected, since the ZX scene is bigger, that someone would have published something. But even of the extended Russian versions "Elite 2 / Elite 3" there is no source code to be found.
The MSX has been given a completely independent version, but there is nothing to be found there either.
Using the color tables, I was able to locate the various menus (marketplace, planet info, galactic / local map, etc.) and I want to trace through the galactic map in order to locate the graphic functions, among other things. Perhaps I can use the graphics functions to track down the problem of why the supposedly cleanly converted data is not drawn. Somewhere the whole calculation has to lead to a list of coordinates according to which the lines are to be drawn.
Attached are the CPC ship definitions for comparison with the 6502 versions, structure definitions as a c-header file and, if one want to debug, a symbol table for the first recognized functions for Winape.
Holy cow! I didn't know it's a Spectrum port - and still that quick!
However, looking at Starglider / Starfox the speed difference is visible.
Great project! Good luck! :) :) :)
Quote from: GUNHED on 02:21, 23 July 21
Holy cow! I didn't know it's a Spectrum port - and still that quick!
However, looking at Starglider / Starfox the speed difference is visible.
Great project! Good luck! :) :) :)
Although based on the Speccy version, it's pretty obvious a fair bit of effort went into improving the code for the Amstrad specifically. The Speccy version didn't have colour planets for example.
Quote from: andycadley on 08:12, 23 July 21
Although based on the Speccy version, it's pretty obvious a fair bit of effort went into improving the code for the Amstrad specifically. The Speccy version didn't have colour planets for example.
Maybe, but it still uses the speccy screen and then converts it to CPC.
It sounds like there's a lot of room for improvement when it comes to the graphics rendering pipeline.
I was able to successfully narrow down the drawing routine for the circles, even if I don't quite understand the mechanics behind it. I have no idea whether you can put a mask on the outer boundary or I just haven't found it yet. The code modifies itself to set a mask, but that only affects the rough inside of the circle. I might guess that these bytes are simply drawn from a table depending on the radius.
The spectrum also has filled circles, e.g. used for the sun. They probably had to make compromises because of the color clashing and made the decision to leave it to simple circles. Filled planets and xored vector graphics probably didn't look that good.
Thanks to Breakpoint on memory change I have found the drawing routine for the lines.
Actually, there are two routines, I suspect a dependence on the direction in which should be drawn.
At address position 0x800d, the one and 0x8025 is directly following the other.
putPixelbyteRoutine1 XREF[3]: ram:7d37(j), ram:8020(j),
ram:8023(j)
ram:800d 7e LD A,(HL)
ram:800e b1 OR C
ram:800f 77 LD (HL),A
ram:8010 15 DEC D
ram:8011 c8 RET Z
ram:8012 7b LD A,E
ram:8013 80 ADD A,B
ram:8014 5f LD E,A
ram:8015 3005 JR NC,LAB_ram_801c
LAB_ram_8017+1 XREF[0,1]: ram:7d14(W)
ram:8017 cb09 RRC C ; or rlc c
ram:8019 3001 JR NC,LAB_ram_801c
LAB_ram_801b XREF[1]: ram:7d1b(W)
ram:801b 2c INC L ; or dec l
LAB_ram_801c XREF[2]: ram:8015(j), ram:8019(j)
ram:801c 7d LD A,L
LAB_ram_801d XREF[1]: ram:7d22(W)
ram:801d c640 ADD A,0x40 ; unchanged byte 0xc6; next Screenline of Background-Bitmap
ram:801f 6f LD L,A
ram:8020 30eb JR NC,putPixelbyteRoutine1
LAB_ram_8022 XREF[1]: ram:7d29(W)
ram:8022 24 INC H ; unchanged byte 0x24
ram:8023 18e8 JR putPixelbyteRoutine1
putPixelbyteRoutine2 XREF[3]: ram:7d7b(j), ram:8038(j),
ram:803b(j)
ram:8025 7e LD A,(HL)
ram:8026 b1 OR C
ram:8027 77 LD (HL),A
ram:8028 15 DEC D
ram:8029 c8 RET Z
ram:802a 7b LD A,E
ram:802b 80 ADD A,B
ram:802c 5f LD E,A
ram:802d 3007 JR NC,LAB_ram_8036
ram:802f 7d LD A,L
LAB_ram_8030 XREF[1]: ram:7d58(W)
ram:8030 c640 ADD A,0x40 ; unchanged byte 0xc6
ram:8032 6f LD L,A
ram:8033 3001 JR NC,LAB_ram_8036
LAB_ram_8035 XREF[1]: ram:7d5f(W)
ram:8035 24 INC H ; unchanged byte 0x24
LAB_ram_8036+1 XREF[2,1]: ram:802d(j), ram:8033(j),
LAB_ram_8036 ram:7d66(W)
ram:8036 cb09 RRC C ; or rlc c
ram:8038 30eb JR NC,putPixelbyteRoutine2
LAB_ram_803a XREF[1]: ram:7d6d(W)
ram:803a 2c INC L ; or dec l
ram:803b 18e8 JR putPixelbyteRoutine2
A central location for the LINEDRAWs takes on the routine at address 0x7EFC, which calculates the byte address of a coordinate in the offscreen bitmap
todo_CalcPointAdressinBitmap XREF[4]: ram:7ccc(c), ram:7cd9(c),
ram:7e9a(c), ram:7ed8(c)
ram:7efc c5 PUSH BC
ram:7efd d5 PUSH DE
ram:7efe d9 EXX
ram:7eff c1 POP BC ; startcoordinates?
ram:7f00 d1 POP DE ; endcoordinates?
ram:7f01 cb4a BIT 0x1,D ; purpose unknown
ram:7f03 2005 JR NZ,LAB_ram_7f0a
ram:7f05 3e7f LD A,0x7f
ram:7f07 80 ADD A,B
ram:7f08 1803 JR LAB_ram_7f0d
LAB_ram_7f0a XREF[1]: ram:7f03(j)
ram:7f0a 3e7f LD A,0x7f
ram:7f0c 90 SUB B
LAB_ram_7f0d XREF[1]: ram:7f08(j)
ram:7f0d 47 LD B,A
ram:7f0e cb42 BIT 0x0,D
ram:7f10 2805 JR Z,LAB_ram_7f17
ram:7f12 3e3f LD A,0x3f
ram:7f14 81 ADD A,C
ram:7f15 1803 JR .calcAdressforBM
LAB_ram_7f17 XREF[1]: ram:7f10(j)
ram:7f17 3e3f LD A,0x3f
ram:7f19 91 SUB C
.calcAdressforBM XREF[1]: ram:7f15(j)
ram:7f1a 48 LD C,B
ram:7f1b 2602 LD H,0x2 ; 16k memory Block (0..3)
ram:7f1d 6f LD L,A ; Adresscalculation (Memblock*2+1)*32 + x/4 (because of 4 Pixel per
; Byte in Mode 1) + y*64
ram:7f1e 29 ADD HL,HL
ram:7f1f 24 INC H ; make Sure the Calculation leads to Adress 0xa000 (upper 8k of block 2)
ram:7f20 29 ADD HL,HL
ram:7f21 29 ADD HL,HL
ram:7f22 29 ADD HL,HL
ram:7f23 29 ADD HL,HL
ram:7f24 29 ADD HL,HL
ram:7f25 79 LD A,C
ram:7f26 cb3f SRL A
ram:7f28 cb3f SRL A
ram:7f2a 85 ADD A,L
ram:7f2b 6f LD L,A
ram:7f2c 79 LD A,C
ram:7f2d e603 AND 0x3 ; Pixellocation in the byte?
ram:7f2f 3c INC A
ram:7f30 47 LD B,A
ram:7f31 0e11 LD C,0x11
LAB_ram_7f33 XREF[1]: ram:7f35(j)
ram:7f33 cb09 RRC C
ram:7f35 10fc DJNZ LAB_ram_7f33
ram:7f37 43 LD B,E
ram:7f38 1e80 LD E,0x80
ram:7f3a d9 EXX
ram:7f3b c9 RET
And then there is another nice part that modifies the drawing routines at runtime
todo_drawJumpEntrypoint2 XREF[6]: ram:7ce2(j), ram:7f62(j),
ram:7f65(j), ram:7f6e(j),
ram:7f71(j), ram:7f7e(j)
ram:7ce5 d9 EXX
ram:7ce6 fe02 CP 0x2
ram:7ce8 3002 JR NC,LAB_ram_7cec
ram:7cea 3e02 LD A,0x2
LAB_ram_7cec XREF[1]: ram:7ce8(j)
ram:7cec 3d DEC A
ram:7ced 57 LD D,A
ram:7cee d9 EXX
ram:7cef 7a LD A,D
ram:7cf0 e61c AND 0x1c
ram:7cf2 fe0e CP 0xe
ram:7cf4 3044 JR NC,manipulate_drawroutine2
ram:7cf6 fe06 CP 0x6
manipulate_drawroutine1 XREF[3]: ram:73a8(c), ram:7450(c),
ram:746b(c)
ram:7cf8 300c JR NC,LAB_ram_7d06
ram:7cfa fe02 CP 0x2
ram:7cfc 212d01 LD HL,0x12d ; 0x01 to change from 0xcb,0x09 "RRC C" to 0xcb,0x01 "RLC C"; 0x2d to
; change from 0x2c "INC L" to 0x2d "DEC L"
ram:7cff 1124c6 LD DE,0xc624 ; dont know, why its here, because nothing is changed and the code left
; by add a,0x40 and inc h
ram:7d02 380f JR C,.md1_patchcommands
ram:7d04 180a JR LAB_ram_7d10
LAB_ram_7d06 XREF[1]: ram:7cf8(j)
ram:7d06 fe0a CP 0xa
ram:7d08 212c09 LD HL,0x92c ; switches codes to "rrc c" and "inc l"
ram:7d0b 1124c6 LD DE,0xc624 ; has no effect as nothing changes
ram:7d0e 3803 JR C,.md1_patchcommands
LAB_ram_7d10 XREF[1]: ram:7d04(j)
ram:7d10 cbe2 SET 0x4,D
ram:7d12 1c INC E
.md1_patchcommands XREF[2]: ram:7d02(j), ram:7d0e(j)
ram:7d13 7c LD A,H
ram:7d14 321880 LD (LAB_ram_8017+1),A ; RLC C
ram:7d17 324b80 LD (LAB_ram_804a+1),A ; RLC C
ram:7d1a 7d LD A,L
ram:7d1b 321b80 LD (LAB_ram_801b),A ; inc l
ram:7d1e 324e80 LD (LAB_ram_804e),A ; inc l
ram:7d21 7a LD A,D
ram:7d22 321d80 LD (LAB_ram_801d),A ; add a,0x40
ram:7d25 325080 LD (LAB_ram_8050),A ; add a,0x40
ram:7d28 7b LD A,E
ram:7d29 322280 LD (LAB_ram_8022),A ; inc h
ram:7d2c 325580 LD (LAB_ram_8055),A ; inc h
ram:7d2f d9 EXX
ram:7d30 3af18c LD A,(BYTE_ram_8cf1)
ram:7d33 a7 AND A
ram:7d34 c23d80 JP NZ,LAB_ram_803d
ram:7d37 c30d80 JP putPixelbyteRoutine1
manipulate_drawroutine2 XREF[1]: ram:7cf4(j)
ram:7d3a fe16 CP 0x16
ram:7d3c 300c JR NC,LAB_ram_7d4a
ram:7d3e fe12 CP 0x12
ram:7d40 2124c6 LD HL,0xc624 ; has no effect as nothing changes
ram:7d43 112d01 LD DE,0x12d ; changes codes to "RLC C" and "DEC L"
ram:7d46 380f JR C,.md2_patchcommands
ram:7d48 180a JR LAB_ram_7d54
LAB_ram_7d4a XREF[1]: ram:7d3c(j)
ram:7d4a fe1a CP 0x1a
ram:7d4c 2124c6 LD HL,0xc624 ; has no effect as nothing changes
ram:7d4f 112c09 LD DE,0x92c ; changes codes to "RRC C" and "INC L"
ram:7d52 3803 JR C,.md2_patchcommands
LAB_ram_7d54 XREF[1]: ram:7d48(j)
ram:7d54 cbe4 SET 0x4,H
ram:7d56 2c INC L
.md2_patchcommands XREF[2]: ram:7d46(j), ram:7d52(j)
ram:7d57 7c LD A,H
ram:7d58 323080 LD (LAB_ram_8030),A
ram:7d5b 326680 LD (LAB_ram_8066),A
ram:7d5e 7d LD A,L
ram:7d5f 323580 LD (LAB_ram_8035),A
ram:7d62 326b80 LD (LAB_ram_806b),A
ram:7d65 7a LD A,D
ram:7d66 323780 LD (LAB_ram_8036+1),A
ram:7d69 326d80 LD (LAB_ram_806c+1),A
ram:7d6c 7b LD A,E
ram:7d6d 323a80 LD (LAB_ram_803a),A
ram:7d70 327080 LD (LAB_ram_8070),A
ram:7d73 d9 EXX
ram:7d74 3af18c LD A,(BYTE_ram_8cf1)
ram:7d77 a7 AND A
ram:7d78 c25880 JP NZ,LAB_ram_8058
ram:7d7b c32580 JP putPixelbyteRoutine2
[code]
I wonder what has to be changed at the drawingroutines to draw for mode 0. As there exists an interrupt driven colorsplit, inserting the GA-Commands for modesplit should be no problem.
Oooh interesting.
Will the purpose of this project be to speed up the gameplay? I remember it plays a lot slower than the BBC original and that made me sad when I saw them compared :(
I still have no idea where the project will take me. I still want to patch the additional ships in and have still no idea, why its not showing them.
A first milestone has been reached, the source code has been reconstructed to such an extent that all data and code areas are clearly uncovered and the assembler can turn it into an executable program.
Now I want to try to relocate parts of the program to move the screen memory to 0x4000. Move all routines that are now in memory bank 1 to memory bank 3. And move the parts that are "behind" the screen memory to 0x4000.
If that works, look to get rid of the offscreen bitmap and draw directly into the screenmemory
And if that works: try double buffering. If I got it right:
Banking mode C1 results in memory banks 0,1,2,7 and C3 results in memory banks 0,3,2,7.
So both banks for the screen memory are always at central 0x4000-0x7fff and an always present bank 7 for the code from 0xc000-0xffff.
Since the CRTC can only see the original memory banks 0..3, and not the switched ones, it should be possible to organize which of the banks is to be displayed when when drawing operations are completed.
C1: 0,1,2,7, drawing in bank 1, displaying original bank 3 at 0xc000
C3: 0,3,2,7, drawing in switched-in bank 3, displaying original bank 1 at 0x4000
With luck, Elite will run faster because copying from the offscreen bitmap to the screen memory is no longer necessary.
It should be possible to adapt the drawing routines to the image memory organization of the CPC with relatively little effort.
Yes, that is great what you're doing - get to grips with the code and place/arrange it more suited to the Amstrad and how you can understand it, etc. I get it.
Then it'll be interesting to see what improvements are gained and what can be done.
Obviously at that point I'd say priority for me would be improving the speed.
But I didn't know ships were missing. Are many missing compared to the BBC version?
When this is achieved I'd definitely be interested in streaming this to my audience on Twitch etc.
We are missing 12 ships and one Station.
Boulder
Shuttle
Transporter
Boa
Anaconda
Mamba
Adder
Gecko
CobraMk1
Worm
Moray
Constrictor
Dodecahedron Station
You can gain a further 16kb if you can put some code into ROM - since ROM is readonly, you can leave it paged in always over the screen RAM - and as long as you don't put variables in that area, you can just write to the paged in ROM and it will go to screen RAM. Of course that limits the game to those who have a ROM board of some type.
Time for a little Experiment.Insert on the english Version in Elite.bas, before the CALL &1C82, POKE &1EDF,8. Its a counter for the copyloop of the Framebuffer, and sets it to copy only half of the Framebuffer to the screen, enough to see an increase of fps. Compare it with an parallel running Emulator.
So avoiding the Framebuffer and going to Doublebuffering will lead to a massive boost in fps.
The Cockpit has also Transferroutines, but i have not found yet the Routines where the Indicators where drawn.
Thats the bigger Part of the screen and don't use unrolled LDIs for the transfer to the screenmemory.
i wonder if you have disassembled it that far, whether it can have a Raspberry Pi patch for the CPC's Raspberry Pi card? There is a tube port for BBC which gives it a performance boost - i wonder if the CPC would gain a similar performance boost?
The program is almost completely disassembled.
But I don't know what a patch for the card could look like and what it should do. Somebody else can do that as soon as I've published the source code.
I have serious problems recognizing the mathematical functions. I can see them roughly in the program flow, but I don't know what which function actually does. There may also be potential for acceleration in the math routines, as the index registers are used a lot, but that is far beyond my knowledge, and maybe not neccessary, as the biggest brake, however, is the transfer from the framebuffer to the screen memory.
In my opinion, the render pipeline is a bit too long because it sorts out which lines are to be drawn predominantly horizontally and which lines are predominantly to be drawn vertically.
That made sense with the 6502s, where the lines were drawn without double buffering and then immediately deleted, but led also to extreme flickering.
This drawing strategy means that a large part of the ship's dimension is always present on the screen and the ship is easier to recognize. BBC may currently have better FPS, but it is flickering and has very noticeable drops in the frame rate.
This drawing strategy makes no sense when drawing in a backbuffer. You can just go ahead and draw and when the scenery is finished, just show it. Bresenham is already used for drawing, they "only" have to be adapted to the memory organization of the CPC and draw directly into the screen memory.
RASM says:------ statistics ------------------
1 file
0 binary include
90163 words
2451 labels
0 struct
0 var
33529 expressions
0 macro
67 aliass
3 ORG zones
261 virtual spaces
327909 bytes of pure code
474 Labels have been named, many with todo-flags for further inspection
I retraced the drawing routines after the line drawing was halfway adapted to the screen memory.
The drawing itself works, but the number of line segments doesn't fit. Somewhere there is still something in the Bresenham algorithm that calculates the line length incorrectly if you feed it with memory addresses from the CPC screen memory.
At least I was able to find where the data for the vertices, edges and faces are read out and identify another data field in the header and had to try it out right away.
Et voila: The Constrictor
Hi There
My favourite game for the CPC!...
Now the code has been disassembled, any trace of unknown missions!
As far as I remember there was only one mission in the whole game....
/Ygdrazil
Quote from: Fessor on 19:44, 31 July 21I retraced the drawing routines after the line drawing was halfway adapted to the screen memory.
The drawing itself works, but the number of line segments doesn't fit. Somewhere there is still something in the Bresenham algorithm that calculates the line length incorrectly if you feed it with memory addresses from the CPC screen memory.
At least I was able to find where the data for the vertices, edges and faces are read out and identify another data field in the header and had to try it out right away.
Et voila: The Constrictor
Quote from: Ygdrazil on 10:05, 02 August 21
Hi There
My favourite game for the CPC!...
Now the code has been disassembled, any trace of unknown missions!
As far as I remember there was only one mission in the whole game....
/Ygdrazil
I know of two Missions: The Asp with the Cloaking device and the Mission where a Sun goes Supernova. I don't know if there are more, but i havent not yet dumped out all strings in cleartext.
Actual i have Problems to change this code to give me the Address of a Pixel in CPC-Screen-Memory instead of its Position in the Linear-Bitmap at 0xa000.
LC C,B ; Save X-Coordinate in C
; Adresscalculation (Memblock*2+1)*32 + x/4 (because of 4 Pixel per Byte in Mode 1) + y*64
LD H,0x2 ; 16k memory Block (0..3)
LD L,A ; Load Y-Coordinate to L
; Calcs y in Bitmap;
ADD HL,HL ; * 2
INC H ; Leads to 0xAxxx
ADD HL,HL ; * 4
ADD HL,HL ; * 8
ADD HL,HL ; * 16
ADD HL,HL ; * 32
ADD HL,HL ; * 64
LD A,C ; C = X-Coordinate
SRL A ; / 2
SRL A ; / 4 - Because 4 Pixels in a Byte
ADD A,L ; Add to ScreenCoordinate (H = Y, L = x)
LD L,A
LD A,C ; Get Coordinate
AND 0x3 ; Masks Pixellocation in the byte
INC A
LD B,A
LD C,0x11 ; Colormask of the Mode 1-Pixel
LAB_ram_7f33
RRC C ; Rotate it to the Correct Position in the Byte
DJNZ LAB_ram_7f33
LD B,E
LD E,0x80
EXX
RET
Quote from: Fessor on 00:35, 03 August 21
I know of two Missions: The Asp with the Cloaking device and the Mission where a Sun goes Supernova. I don't know if there are more, but i havent not yet dumped out all strings in cleartext.
Actual i have Problems to change this code to give me the Address of a Pixel in CPC-Screen-Memory instead of its Position in the Linear-Bitmap at 0xa000.
LC C,B ; Save X-Coordinate in C
; Adresscalculation (Memblock*2+1)*32 + x/4 (because of 4 Pixel per Byte in Mode 1) + y*64
LD H,0x2 ; 16k memory Block (0..3)
LD L,A ; Load Y-Coordinate to L
; Calcs y in Bitmap;
ADD HL,HL ; * 2
INC H ; Leads to 0xAxxx
ADD HL,HL ; * 4
ADD HL,HL ; * 8
ADD HL,HL ; * 16
ADD HL,HL ; * 32
ADD HL,HL ; * 64
LD A,C ; C = X-Coordinate
SRL A ; / 2
SRL A ; / 4 - Because 4 Pixels in a Byte
ADD A,L ; Add to ScreenCoordinate (H = Y, L = x)
LD L,A
LD A,C ; Get Coordinate
AND 0x3 ; Masks Pixellocation in the byte
INC A
LD B,A
LD C,0x11 ; Colormask of the Mode 1-Pixel
LAB_ram_7f33
RRC C ; Rotate it to the Correct Position in the Byte
DJNZ LAB_ram_7f33
LD B,E
LD E,0x80
EXX
RET
If you have a few hundred spare bytes just use a look-up table. Feed in the Y, and get a straight screen address back. If the Y is always between 0-127 which I assume it would be you can 256 byte boundary the screen address data so its really quick
ADD A ;Double the Y so 8 bit result to 16Bit
LD L,A ;Load the Low byte with Y
LD H,screentable/256 ; H=High Byte Address table start
LD A,(HL)
INC L
LD H,(HL)
LD L,A
Maybe? ???
Also use a table for the pixel rotation and mask too
Quote from: Fessor on 00:35, 03 August 21Actual i have Problems to change this code to give me the Address of a Pixel in CPC-Screen-Memory instead of its Position in the Linear-Bitmap at 0xa000.
As Trebment suggests, a lookup table would be the faster, and if you're making it 128k, you presumably have the memory.
I threw together a bit of a quick stab at calculating directly to video memory if you're interested though - assuming a &4000 base as you mentioned in a previous post and the same registers holding x & y. Only gave it a quick couple of tests, so it might not be correct or contain oversights, and I hate the presence of the jumps, but the results looked OK.
ld c,b
ld l,a
and a,7
ld h,a ; 3 lsb of y need to be multiplied by &800, or 256*8, so this is the *256
ld a,l
and a,&f8 ; 3 msb will be 3 lsb of h, middle two become 2 msb of L
add a,a
rl h
add a,a
rl h
add a,a
rl h
ld l,a
set 6,h ; assume base &4000
ld a,c
ld c,&88
srl a
jr nc,Bit0is0
rrc c
.Bit0is0
srl a
jr nc,Bit1is0
rrc c
rrc c
.Bit1is0
or a,l
ld l,a ; masked in x offset for final screen address
Quote from: Axelay on 11:37, 03 August 21
As Trebment suggests, a lookup table would be the faster, and if you're making it 128k, you presumably have the memory.
I threw together a bit of a quick stab at calculating directly to video memory if you're interested though - assuming a &4000 base as you mentioned in a previous post and the same registers holding x & y. Only gave it a quick couple of tests, so it might not be correct or contain oversights, and I hate the presence of the jumps, but the results looked OK.
ld c,b
ld l,a
and a,7
ld h,a ; 3 lsb of y need to be multiplied by &800, or 256*8, so this is the *256
ld a,l
and a,&f8 ; 3 msb will be 3 lsb of h, middle two become 2 msb of L
add a,a
rl h
add a,a
rl h
add a,a
rl h
ld l,a
set 6,h ; assume base &4000
ld a,c
ld c,&88
srl a
jr nc,Bit0is0
rrc c
.Bit0is0
srl a
jr nc,Bit1is0
rrc c
rrc c
.Bit1is0
or a,l
ld l,a ; masked in x offset for final screen address
Yeah, tried that already, but got also garbage on screen and after some lines drawn a crash.But, i think, im looking at the wrong place. Because this changes in the code are shifting the addresses of the Musicplayer i simply uncommented the loading-routines for it to deactivate it this way. But this results in addresschanges earlier in the code and shifting more routines to lower addresses.And somewhere in there must be a routine that reacts allergic to this and maybe expects something on a 256byte-boundary.I tried to start a game with original-draw routines reactivated and outcommented loading-routines, departed from the spacestation, and in rearview got very weird drawing and extreme slowdown before the game crashes.After reactivating the loading of the Musicroutines the game runs normal.
I hate this kind of error...
So, after many crashes i managed to patch the linedrawing-routines to draw to screenmemory.
A clearly noticeable increase in the fps, but just as clearly noticeable drop when there is a lot to be drawn.
But that is also noticeable in the unpatched version ...Its not playable and only a demonstration of how much fps we could get with doublebuffering.Simply start ELITEP.BAS
I hope that somebody with better knowledge will take a look at the drawing routine when I publish the source, for possible optimisation. At least it works ...
Thanks to https://www.bbcelite.com/ (https://www.bbcelite.com/) I am a bit torn as they explain the code of the BBC version very well and also how the different versions have been expanded. And then that brings me to the shipsets. Even if the BBC's disc version has all ships, not all of them are available at the same time, only a part of them. Depending on the tech level / government of the target system, other ship models are used to fill roles. Pirate ships like the Krait or Sidewinder are replaced in more dangerous systems by stronger opponents like Mamba or Gecko. Basically, only one set of 15 ship types is currently active.
https://www.bbcelite.com/deep_dives/ship_blueprints_in_the_disc_version.html (https://www.bbcelite.com/deep_dives/ship_blueprints_in_the_disc_version.html)
Our disc version should now also be able to be adapted, like the BBC version, not only to determine the color variation and positioning of the planet, the sun and the space station when entering a new system, but also which ships are allowed to appear in this system and then load the table and ship definitions accordingly.
I am still missing the meaning of a few data fields in the ship definitions, I might find out when looking through the code.
It may open the way to create a disk version for the 464 that contains all ships, but remains with the current graphics with offscreen buffer.
And a version for 6128 with double buffering and data storage in the memory banks so that there are no interruptions due to the loading of data, depending on the situation.
Amazing work so far!
In the attachment you will find my current working version for the RASM assembler. About 30% of the functions are identified. Please do not publish on other sites.
(I wish RASM could output a new, cleaned up listing of the active code passages without the passages switched off with if / ifnot)
I don't understand the math routines with their tables in order to label them properly. My adjustments to the line draw routine are also a quick hack. I hope that someone with better assembly knowledge can take a look at it and possibly improve it.
For Textprinting and Circledrawing they have switches where to draw (offscreen or in screenmem), for linedrawing unfortunately not.But with possible switch to double buffering, these are code passages that can be dropped and a lot of bytes can be used for other purposes
In the structures there are some flags whose meaning I have not yet identified, but which apparently control the behavior of the AI.
Attached is a fresh version with bug fixes in the naming of some labels and other revealed functions.
For the ship slots I have set field labels everywhere to make it easier to debug how the flags change.
I'm hoping that something like a destination number would appear in the flags. But unfortunately that only seems to be the case with the missiles so that they know which target they have to fly to.
I think it would be nice if the ships could fight with each other.
So I uncovered and looked at the subroutines for firing the laser.
When firing the own laser, the status of the hit target is set to hostile and only one other flag is changed, but apparently no record of who hit the target.
The hostility seems to be directed against the player only.
So next I have to find the subroutines for the behavior of a hostile ship. After all, there must be variables so that the opponents know what to shoot at.
I just converted this https://www.bbcelite.com/disc/flight/subroutine/lships.html
Routine for an extendend Disk Version to support different Shipsets
call getRandomNumber
and 3 ; to get four different Shipsets for a System
ld b,a
ld a,(Government) ; sort out after dangerousness
cp 3 ; 0..3 Feudal to Dictatorship
rl b ; rotate Carry into LSB of Reg B
ld a,(Techlevel) ;
cp 10 ; Advanced Systems have a Dodo instead of a Coriolis
rl b ; rotate Carry into LSB of Reg B
ld a,b ;
add 'A' ; To get a valid Char for the Filename
That gives a nice Matrix, basing on 2bit Random, 1 bit for Government and 1 bit for Techlevel
Zaonce: Corporate State, Techlevel 12: A,E,I,M
Lave: Dictatorship, Techlevel 5: B,F,J,N
Xezaor: Multi-Government, Techlevel 11: C,G,K,O
Zaalela: Feudal, Techlevel 5: D,H,L,P
A first Run with Files containg the Dodo or containing the Coriolus was successfull
At entering the Hyperspace it now loads one of the four possible Shipsets for the System.
Now its time to convert the Shipdata and look how to fill the Tables.
Hi!
I looked at some of the tables in the sources. The ones at 0x4600 (low byte values) and 0x4700 (high byte values) together form a quadratic table it seems.
I added a HTML/Javascript file in the ZIP that draws the length in a window (1080p screen preferred). The graph with the many peaks are the values of 0x4600, the smaller curve the values of the table at 0x4700, and lastly the big curve contains the values of the same indices from both tables combined (table1-index + 256*table2-index). I divided the results of the latter values by 75 to make the whole graph visible in the browser.
MaV
So, in the attachments is the first beta of the extended disk version for all CPCs as well as the current source code. Please do not upload to other sites as it is not the final version yet. (Actually only the music player needs to be adjusted).
What has been expanded / changed:
- Splashscreens 1 and 2 revised, Splashscreen 2 is now a showcase similar to the 16bit Elites.
- The mechanics of the BBC disk version, which reloads various shipsets, have been reproduced.
- In the savegames it is now noted which shipset is active, they are therefore incompatible with the officially published versions, so you have to start a new career.
- Routines for loading / saving savegames in order to be compatible with future changes to the game (encryption against program code deactivated)
- Unused code commented out and a little over 1000 bytes gained. This may be enough to retrofit the two missing missions (Hunting the Constrictor / delivering Thargoid-Plans), but I have to take a closer look at that in the BBC code.
Another small experiment to better estimate the memory requirements: Localization
It would have been too easy to simply copy the tables from the other language versions ...
Seems that the French version has extra code to create the special characters and some text placements seem to be hard coded ...
With the next release, a potential crash will be fixed, which can rarely occur if you let the showcase run longer in the second splash screen. Even if it looks clean to save the loop counter for djnz with push / pop, strangely enough it is possible to break out from time to time by pressing the space bar and leave the stack in a faulty state.
(The showcase has also been refined a bit and now takes into account their individual maximum view distance)
I think I will also switch off this "Boarded by Pirates", which can rarely occur every now and then when docking, as it is extremely annoying when you have just barely survived several fights and have just reached the space station with a heavily collapsed spaceship (destroyed docking computer, destroyed energy unit, fuel leak ...) and then get a game over with this message ...
This event is no fun and IMHO just annoying.
I didnt know there was this game over in Elite.
Any news about this next release ?
Quote from: Fessor on 12:33, 05 September 21
Another small experiment to better estimate the memory requirements: Localization
It would have been too easy to simply copy the tables from the other language versions ...
Seems that the French version has extra code to create the special characters and some text placements seem to be hard coded ...
Not speaking for all french people here but i think this is perfectly understandable without the accents. I suppose some products description could be abbreviated or adapted: Prod. de luxe, Prod. Aliens instead of Prod. Etrangers, Spiritueux instead of Vins/Liqueurs. Nice work!
Progress is extremly slow at the moment, to say at least. Since my last Post I had shot down my Gitbucket with an update on my NAS, it took a lot of time to get it running again without losing my repositories.
To a certain degree I fixed the new splash screen so that Elite doesn't crash here anymore. However, I have not yet managed to arrange the code in such a way that banking works as a prerequisite for doublebuffering. I suspect it's because some functions have their own stack areas and are allergic to this.
The title music also does not want to be integrated yet. Although the code for the intro overwrites unused routines in memory and is called in the interrupt for the color split as before, something is not compatible with "my" new splash screen and after a few iterations the stack is corrupt, although the code actually looks clean.
In between, I also took a closer look at the French language version; they added four more text functions there for the accents and some string numbers changed as a result.
I've also started to take a closer look at the German language version, there are even bigger differences in the string numbers. But I didn't look to see if there were any major differences in the code compared to the English/French version yet.
It's a Sysiphus task to rework all the text calls and replace the still hard-coded string numbers with equates in the first pass for the english Version
CALL printFollowingTokenWithSpace
db 3
to
CALL printFollowingTokenWithSpace
db token03
And then defining the Lists for the French/German Version.I hope that there are no differences in the keyboard query of the versions, but I haven't looked at it yet.