FAQ  •  Register  •  Login

Cargas de Produndidad / Depth Charge

Moderator: nitrofurano

<<

oblo

Posts: 96

Joined: Tue Jul 12, 2011 5:23 pm

Post Sun Nov 04, 2018 5:47 pm

Cargas de Produndidad / Depth Charge

Hi all, long time no see :)

Thanks to some spare time, I had the opportunity to retake the speccy programming, so here is my last creation: a clone of the Depthcharge arcade game. Nothing fancy, but at least I could have some fun developing for ours old but reliable Spectrums.
Game mechanic is simple: move your ship left and right and drop charges to destroy submarines, while avoiding their missiles. Number of submarines and missiles can be chosen at each game start.
Image


The file attached contains:
- .TAP Spanish version
- .TAP English version
- Source code for both versions
- A 'readme.txt' file

Hope you enjoy and as always, any comments are welcome. Cheers!
Attachments
Cargas-Depthcharge.7z
(13.15 KiB) Downloaded 86 times
<<

boriel

Site Admin

Posts: 1557

Joined: Wed Nov 01, 2006 6:18 pm

Location: Santa Cruz de Tenerife, Spain

Post Tue Nov 06, 2018 10:25 pm

Re: Cargas de Produndidad / Depth Charge

Woooow! :shock:
Super!!

Thanks for sharing!
<<

britlion

Posts: 798

Joined: Mon Apr 27, 2009 7:26 pm

Location: Slough, Berkshire, UK

Post Wed Nov 14, 2018 5:45 pm

Re: Cargas de Produndidad / Depth Charge

Very nice little fun thing. Good job.

By the way, my sneaky fast t() function is:

  Code:
FUNCTION t() as uLong
asm
    DI
    LD DE,(23674)
    LD D,0
    LD HL,(23672)
    EI
end asm
end function


Which saves a lot of maths and division. If you want to divide by 50 to get whole seconds, you can do it outside the function - but generally, I found t() returning clock ticks and working with them as 50 times larger meant I have more precision on where I launch events. (Instead of at 1s, 2s, 3s, I go 50 frames, 100 frames, 150 frames - and then if I want to I can tweak that to 40,80,120 much more easily).

I notice you are actually using it in the line:
a = t1 / 30 * PI

So to get t you do a lot of stack work, then divide by 50 - and then divide by 30. I think I'd do it as frames and divide by 150 in one go when setting a, which is probably shorter than running the full division twice.

Anyway. Just my thougts. The game is quite fun :D Never enough depth charges.
<<

oblo

Posts: 96

Joined: Tue Jul 12, 2011 5:23 pm

Post Sun Nov 18, 2018 12:48 am

Re: Cargas de Produndidad / Depth Charge

britlion wrote:Very nice little fun thing. Good job.

By the way, my sneaky fast t() function is:

  Code:
FUNCTION t() as uLong
asm
    DI
    LD DE,(23674)
    LD D,0
    LD HL,(23672)
    EI
end asm
end function


Which saves a lot of maths and division. If you want to divide by 50 to get whole seconds, you can do it outside the function - but generally, I found t() returning clock ticks and working with them as 50 times larger meant I have more precision on where I launch events. (Instead of at 1s, 2s, 3s, I go 50 frames, 100 frames, 150 frames - and then if I want to I can tweak that to 40,80,120 much more easily).

I notice you are actually using it in the line:
a = t1 / 30 * PI

So to get t you do a lot of stack work, then divide by 50 - and then divide by 30. I think I'd do it as frames and divide by 150 in one go when setting a, which is probably shorter than running the full division twice.

Anyway. Just my thougts. The game is quite fun :D Never enough depth charges.


Many thanks! I'm not fond on ASM so any input is very welcome; at least I can compare your code with mine and learn something new :)
Besides, I updated the game with a few improvements: sonar is now draw OK , added a minor visual effect on it, load screen and intro music. And the inlays, shared with my other Escape game.
Spanish inlay: https://drive.google.com/open?id=1aHkpN ... Cfx5sgDVvJ
English inlay: https://drive.google.com/open?id=1TTmyl ... 31KLPwTItz

Cheers.


EDIT: just tried your ASM t() function and it's so fast I can now "play" with the sonar and add more effects :D
Anyway, just to try to understand a bit of ASM with your function:

DI -> disables interruptions, so the program won't interfere with the function
LD DE,(23674) -> load the value of the 23674 address (part of the Spectrum frames system variable) in the DE register (one of the Spectrum 8+8 -pair- bit registers)
LD D,0 -> load 0 into D register (?)
LD HL,(23672) -> load the value of the 23674 address (part of the Spectrum frames system variable) in the HL register (one of the Spectrum 8+8 -pair- bit registers)
EI -> enables interruptions before existing function

But the function, what returns? The sum of all values? And why load a zero value into D? Sorry if they are basic ASM questions, but my knowledge of ASM and the Z80 are almost none.
Attachments
Cargas-Depthcharge_v1.01.7z
Cargas de Profundidad/Depth Charge v1.01
(20.05 KiB) Downloaded 69 times
<<

boriel

Site Admin

Posts: 1557

Joined: Wed Nov 01, 2006 6:18 pm

Location: Santa Cruz de Tenerife, Spain

Post Mon Nov 19, 2018 2:30 pm

Re: Cargas de Produndidad / Depth Charge

Note: You can directly do that in ZXBasic (replacing the ASM function) with:
  Code:
t = PEEK(Ulong, 23672) BAND 0xFFFFFF


It won't be perhaps as fast as the ASM. Can you check it?
<<

oblo

Posts: 96

Joined: Tue Jul 12, 2011 5:23 pm

Post Tue Nov 20, 2018 7:16 am

Re: Cargas de Produndidad / Depth Charge

boriel wrote:Note: You can directly do that in ZXBasic (replacing the ASM function) with:
  Code:
t = PEEK(Ulong, 23672) BAND 0xFFFFFF


It won't be perhaps as fast as the ASM. Can you check it?


Tested and it's way faster than ASM; in fact, I can't control the speed of the sonar pointer. With the ASM function, I can do that changing the 360 in a = t1 / 360 * PI: REM a is the seconds pointer in radians line.
This is how the sonar subroutine is defined right now:
  Code:
REM Rutina del sonar
SUB sonar()

   REM sonido del sonar
   segundos = segundos + 1
   if segundos = 15 then
      beep 0.07,45 : beep 0.13,30
      segundos = 0
      poke 23164+(RND*3),135
      poke 23196+(RND*3),135
      poke 23228+(RND*3),135      
   end if
   
   
   REM grafico del sonar   
   FUNCTION t() as uLong
      asm
            DI
            LD DE,(23674)
            LD D,0
            LD HL,(23672)
            EI
      end asm
   end function

   DIM t1 AS FLOAT
   t1 = t()
   a = t1 / 360 * PI: REM a is the seconds pointer in radians
   sx = 20 * SIN a : LET sy = 20 * COS a
   PLOT 237, 28: DRAW sx, sy
   
   if sx2 <> sx then
      over 1
      PLOT 237, 28: DRAW sx2, sy2
      sx2 = sx : sy2 = sy
      over 0
      CIRCLE 236, 28, 18
      CIRCLE 236, 28, 13
      CIRCLE 236, 28, 8
      plot 236,9 : draw 0,38
      plot 217,28 : draw 38,0
   end if
   
   if sx > 19.9 or sx < -19.9 or (sx > 0 and sx < 3) then
      resetsonar = resetsonar + 1
      if resetsonar = 1 then
         for y = 18 to 23
          print at y,27; "     ";
         next y
         CIRCLE 236, 28, 18
         CIRCLE 236, 28, 13
         CIRCLE 236, 28, 8
         plot 236,9 : draw 0,38
         plot 217,28 : draw 38,0
      end if
   else
      resetsonar = 0
   end if
   
   return
   
END sub



Cheers
<<

boriel

Site Admin

Posts: 1557

Joined: Wed Nov 01, 2006 6:18 pm

Location: Santa Cruz de Tenerife, Spain

Post Tue Nov 20, 2018 11:18 pm

Re: Cargas de Produndidad / Depth Charge

Ups, sorry. For the PEEK, it's in 1/50th of second. You have to divide by 50 to get the real value in seconds.
<<

oblo

Posts: 96

Joined: Tue Jul 12, 2011 5:23 pm

Post Wed Nov 21, 2018 6:01 pm

Re: Cargas de Produndidad / Depth Charge

Negative; after several tests it's still too fast and the radian still goes wild :( Sorry, but this time I'll have to take the ASM approach :wink:

Cheers
<<

britlion

Posts: 798

Joined: Mon Apr 27, 2009 7:26 pm

Location: Slough, Berkshire, UK

Post Mon Dec 03, 2018 3:18 pm

Re: Cargas de Produndidad / Depth Charge

How the heck is the compiled code faster than the ASM one? *blink*

I thought the ASM one was pretty optimal - I can't see how to do it faster. I must check that. Are you sure it's working correctly (if too fast) with it?

The ASM one does:

DI - disable interrupts. Just for a moment, it stops the clock. This means it can't tick mid measure. Technically it will lose a frame very very _very_ rarely, but in practice nobody would notice. It's a safety device to make all the bytes consistent while we read it.

LD DE, (23674) - The clock is at 23672,23763,23674. This loads D up with (23675) and E up with (23674). The contents of 23675 are redundant - it's a 3 byte clock, so we clear D with
LD D,0
LD HL, (23672) loads H with (23673) and L with (23672).
EI - Put interrupts back. We've got our numbers.
end ASM
Back to normal.

So all we've done is copy the clock bytes into DEHL (well, 0+E+H+L)
Since the function returns a uLong, which is 4 bytes in DEHL, it returns this number.

Boriel's peek method is technically not interrupt safe, by the way, though the probability of an interrupt hitting right in the middle of those small set of instructions is fairly low. That said, it's going to happen eventually.
Last edited by britlion on Sun Dec 09, 2018 6:19 pm, edited 3 times in total.
<<

britlion

Posts: 798

Joined: Mon Apr 27, 2009 7:26 pm

Location: Slough, Berkshire, UK

Post Mon Dec 03, 2018 3:20 pm

Re: Cargas de Produndidad / Depth Charge

Doesn't that peek band 63 (FFFFFF) mean that it only returns numbers from 0-63 ? That's a bit short. It rolls over every second and a bit, surely?

Shouldn't it be peek band 0xFFFFFFFFFFFFFFFFFFFFFFFF ?
<<

britlion

Posts: 798

Joined: Mon Apr 27, 2009 7:26 pm

Location: Slough, Berkshire, UK

Post Mon Dec 03, 2018 3:35 pm

Re: Cargas de Produndidad / Depth Charge

  Code:
a = t1 / 360 * PI: REM a is the seconds pointer in radians


Surely this is 50 times too fast? My t() function returns FRAMES, not seconds - so it returns 50ths of a second as a count.
<<

oblo

Posts: 96

Joined: Tue Jul 12, 2011 5:23 pm

Post Mon Dec 03, 2018 8:15 pm

Re: Cargas de Produndidad / Depth Charge

britlion wrote:How the jeck is the compiled cosde faster than the ASM on? *blink*


You are right, my mistake :-S I really wanted to say I didn't know to implement/control the code provided by boriel as opposite as yours, what works "as is", without any modification.
<<

boriel

Site Admin

Posts: 1557

Joined: Wed Nov 01, 2006 6:18 pm

Location: Santa Cruz de Tenerife, Spain

Post Mon Dec 03, 2018 9:19 pm

Re: Cargas de Produndidad / Depth Charge

That Britlion said is what I tried to explain on first place (didn't make myself understood). Anyway, nice game, an congrats :)

Return to Gallery

Who is online

Users browsing this forum: No registered users and 1 guest

cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by Vjacheslav Trushkin for Free Forums/DivisionCore.

phpBB SEO