Welcome, Guest
You have to register before you can post on our site.

Username
  

Password
  





Search Forums

(Advanced Search)

Forum Statistics
» Members: 263
» Latest member: RonaldNat
» Forum threads: 1,074
» Forum posts: 6,434

Full Statistics

Online Users
There are currently 124 online users.
» 0 Member(s) | 121 Guest(s)
Applebot, Bing, Google

Latest Threads
.tap file code not execut...
Forum: Help & Support
Last Post: Zoran
04-28-2025, 10:59 AM
» Replies: 4
» Views: 346
Exit from more than one l...
Forum: Wishlist
Last Post: Duefectu
04-23-2025, 10:06 PM
» Replies: 3
» Views: 302
put small ASM programs li...
Forum: How-To & Tutorials
Last Post: Zoran
04-18-2025, 02:02 PM
» Replies: 6
» Views: 1,608
Creating +3 Menus - Loadi...
Forum: Help & Support
Last Post: merlinkv
04-16-2025, 02:08 PM
» Replies: 6
» Views: 558
Randomize not very random...
Forum: Help & Support
Last Post: Zoran
04-08-2025, 10:40 AM
» Replies: 4
» Views: 896
Scope rules
Forum: Bug Reports
Last Post: Zoran
04-04-2025, 09:46 AM
» Replies: 2
» Views: 340
Using constants not allow...
Forum: Bug Reports
Last Post: baltasarq
03-19-2025, 10:00 PM
» Replies: 8
» Views: 1,070
404 page not found
Forum: Documentation
Last Post: boriel
03-08-2025, 07:16 PM
» Replies: 5
» Views: 2,888
Spectrum keywords codes
Forum: Bug Reports
Last Post: boriel
03-08-2025, 11:00 AM
» Replies: 1
» Views: 421
ZXodus][Engine
Forum: ZX Basic Compiler
Last Post: boriel
02-19-2025, 11:43 PM
» Replies: 69
» Views: 213,820

 
  HOWTO: Put BeepFX Sound into ZXB code
Posted by: britlion - 06-02-2012, 12:28 PM - Forum: How-To & Tutorials - Replies (5)

Shiru's Beepfx (http://shiru.untergrund.net/files/beepfx.zip) is quite an interesting tool for sound effects. He doesn't believe it can be used for tunes - but it can do different pitched "tones" and include pauses, and that spells tune to me. Beepola is probably a better choice for real tune making, though.

Anyway - the asm it produces is not compatible with zxb's assembler. So I did the working out of how to tweak it to work.

So the sound calling routine would look like this:

Code:
SUB sound(soundNum as uByte)
asm
#include "BeepFXPlayer.asm"
#include "SoundData.asm"

SoundEnd:
pop IX

end asm
end sub

And BeepFXPlayer would always be the same tweaks, so I present my version here:

Code:
playBasic:
play:
    ld hl,soundEffectsData    ;address of sound effects data
    di
    push ix
    push iy

    ld b,0
    ld c,a
    add hl,bc
    add hl,bc
    ld a,(hl)
    inc hl
    ld h,(hl)
    ld l,a
    push hl
    pop ix            ;put it into ix
   
    ld a,(23624)    ;get border color from BASIC vars to keep it unchanged
    rra
    rra
    rra
    and 7
    ld (sfxRoutineToneborder+1),a
    ld (sfxRoutineNoiseborder+1),a
   

readData:
    ld a,(ix+0)        ;read block type
    or a
    jr nz,readDatasound
    pop iy
    ei
    jp SoundEnd

readDatasound:
    ld c,(ix+1)        ;read duration 1
    ld b,(ix+2)
    ld e,(ix+3)        ;read duration 2
    ld d,(ix+4)
    push de
    pop iy

    dec a
    jr nz,sfxRoutineNoise



;this routine generate tone with many parameters
sfxRoutineTone:
    ld e,(ix+5)        ;freq
    ld d,(ix+6)
    ld a,(ix+9)        ;duty
    ld (sfxRoutineToneduty+1),a
    ld hl,0
   
sfxRoutineTonel0:
    push bc
    push iy
    pop bc
sfxRoutineTonel1:
    add hl,de
    ld a,h
sfxRoutineToneduty:
    cp 0
    sbc a,a
    and 16
sfxRoutineToneborder:
    or 0
    out ($fe),a
#line 78               
    dec bc
    ld a,b
    or c
    jr nz,sfxRoutineTonel1

    ld a,(sfxRoutineToneduty+1)
    add a,(ix+10)    ;duty change
    ld (sfxRoutineToneduty+1),a

    ld c,(ix+7)        ;slide
    ld b,(ix+8)
    ex de,hl
    add hl,bc
    ex de,hl

    pop bc
    dec bc
    ld a,b
    or c
    jr nz,sfxRoutineTonel0

    ld c,11
nextData:
    add ix,bc        ;skip to the next block
    jr readData



;this routine generate noise with two parameters
sfxRoutineNoise:
    ld e,(ix+5)        ;pitch

    ld d,1
    ld h,d
    ld l,d
sfxRoutineNoisel0:
    push bc
    push iy
    pop bc
sfxRoutineNoisel1:
    ld a,(hl)
    and 16
sfxRoutineNoiseborder:
    or 0
    out ($fe),a
    dec d
    jr nz,sfxRoutineNoisel2
    ld d,e
    inc hl
    ld a,h
    and $1f
    ld h,a
sfxRoutineNoisel2:
    dec bc
    ld a,b
    or c
    jr nz,sfxRoutineNoisel1

    ld a,e
    add a,(ix+6)    ;slide
    ld e,a

    pop bc
    dec bc
    ld a,b
    or c
    jr nz,sfxRoutineNoisel0

    ld c,7
    jr nextData

Finally, you need to run beepfx, and compile just the sound data to asm.

You'll get something like this:

Code:
soundEffectsData
    dw .sfx0

.sfx0
    db #01
    dw #0032,#0064,#01f4,#ffec,#0080
    db #00

This needs some massaging to work. Change "soundEffectsData" to "soundEffectsData:"
Change "." to "soundEffectsData" And make labels have a : on the end.
Search and replace "db" with "defb"
Search and replace "dw" with "defw"
Replace # with $
All done!

Worked example:
Code:
soundEffectsData:
    defw soundEffectsDatasfx0
    defw soundEffectsDatasfx1

soundEffectsDatasfx0:
    defb $01
    defw $0032,$0064,$01f4,$ffec,$0080
    defb $00
soundEffectsDatasfx1:
    defb $01
    defw $0014,$0190,$00c8,$0005,$0110
    defb $01
    defw $001e,$0190,$00c8,$0008,$0110
    defb $00

you can then save this as something lime soundata.asm and #'include this file into the sound routine listed above. Call with sound (n) for the sound number.

Print this item

  Question about the Heap
Posted by: LCD - 05-30-2012, 08:19 AM - Forum: Help & Support - Replies (4)

Hi Boriel, just following easy question:
If I use a heap of 256 bytes, where it is put into memory? I want to know where I cannot put any binary data.
Is this 65535-heapsize?
Edit: May this be problematic if I page the heap out? Is there a possibility that we can put the heap at a selected memory area (e.g. a buffer created with DEFB's) at program start (I know that changing it may crash the program).

Print this item

  Pac Man Project
Posted by: britlion - 05-27-2012, 05:13 PM - Forum: Gallery - Replies (17)

Clearly not finished, but I wanted feedback on how it feels. I spent /ages/ getting complex ghost behaviour right. Compare with CDS gobble a ghost, for example.

<!-- m --><a class="postlink" href="http://dl.dropbox.com/u/4903664/DemoMan.tzx">http://dl.dropbox.com/u/4903664/DemoMan.tzx</a><!-- m -->

(Yes, I know you can't die. Or eat ghosts. Yes, I know it breaks on level 2)

Print this item

  U-Boot hunt
Posted by: LCD - 05-27-2012, 07:47 AM - Forum: Gallery - Replies (5)

Another game finished and waiting for the music. It is one of the "lost games" from my homepage, rewritten and optimised from HiSoft BASIC to ZXBC. Some new stuff also added like a big explosion animation where the frames are compressed with MegaLZ and decompressed while playback. Also Border-effect added on the start screen, but only correctly working on Spectrum 128 in 48K or USR0 mode (In 128K BASIC the border jumps up and down, also it looks that the Spectrum is a bit slower), so DivIDE-users will load it right on their 128K.

.png   u-boothunt.png (Size: 1.27 KB / Downloads: 4107)
The goal is to find a nazi u-boot (submarine) and hit it with a depthcharge. You do not know where the sub is, but you know the distance between explosion and the sub. Easy? I don't think so because there is a limited number of Deptcharges and the sub moves constantly.
Okay, it is not a big game and not so good as Earthraid, but I wanted to release it to not have that many MIA titles in my portfolio.

Print this item

  New game: Earthraid
Posted by: LCD - 05-26-2012, 07:09 PM - Forum: Gallery - Replies (35)


.png   Earthraid.png (Size: 3.03 KB / Downloads: 7148)
Cooming soon: "EARTHRAID". This is a game published in 1986 for the Commodore C64. I made a Spectrum conversion of it. Its allready finished, but waiting now for a soundtrack.

Print this item

  output ASM
Posted by: britlion - 05-02-2012, 10:02 AM - Forum: Bug Reports - Replies (7)

Not sure if this is a bug, per se - but it is certainly a bit ugly.

This even survived the peephole optimizer.

Input Basic:

IF myCurrentVector = %1000 then

Output assembly:

ld a, (ix+9)
sub 8
sub 1
jp nc, __LABEL56


Two subs in a row? And worse "Sub 1" instead of a dec?

It later tests:

IF myCurrentVector = %0001 then

as:
ld a, (ix+9)
dec a
sub 1
jp nc, __LABEL63



And I'm not even convinced that's the same test as "equal to x" Surely that's testing "If myCurrentVector>x" anyway?

Print this item

  Bool
Posted by: slenkar - 04-30-2012, 09:31 PM - Forum: Wishlist - Replies (11)

Are bools supported by zxbasic?

If so, would an array of bools take up only 1/8 of the room as an array of Bytes?

Print this item

  BlitzMax
Posted by: slenkar - 04-30-2012, 03:42 PM - Forum: Wishlist - No Replies

If you (boriel) ever feel you want to re-write the compiler blitzmax would be a good choice, it has similar syntax to python but is a lot faster. It has a regular expressions module too and is crossplatform.

Print this item

  pathfinding
Posted by: slenkar - 04-29-2012, 11:10 PM - Forum: How-To & Tutorials - Replies (2)

you can run the code to get a little demo:

Code:
const found as ubyte=1

const pathsuccess as ubyte=1
const CantCreatePathError as ubyte=2

Dim path as integer

Dim SquareState(32,24) as UByte
Dim SquareParentX(32,24) as Ubyte
Dim SquareParentY(32,24) as Ubyte

Dim HCost(32,24) as UByte

Dim PathToWalkX(255) as UByte
Dim PathToWalkY(255) as UByte
Dim StepsOnPath as Integer
Dim PathBlockedByPerson as Ubyte
Dim PathBlocker as Integer
Dim numberofopenlistitems as Integer
Dim LowestFCostSquareX as Integer
Dim LowestFCostSquareY as Integer


Function FindPath(startx as Integer,starty as Integer,targetx as Integer,targety as Integer) as Integer
ClearPath()
pathfindmessage("FindPath")
If startx =targetx And starty = targety then
pathfindmessage("target square = start square")
Return 3
End if

HCost(startx,starty)=GetHCost(startx,starty,targetx,targety)
      AddToOpenList(startx,starty,startx,starty)
LowestFCostSquareX=startx
LowestFCostSquareY=starty

path=-1
Dim DebugIter as Integer

while path=-1
DebugIter=DebugIter+1

If DebugIter>200 then
pathfindmessage("path too long")
Exit While
End if

If numberofopenlistitems=0 then
pathfindmessage("no more open list items")
Exit While
End if
'pathfindmessage("Lowest f cost square "+STR(LowestFCostSquareX)+" "+STR(LowestFCostSquareY))

Dim lowx as ubyte
lowx=LowestFCostSquareX
Dim lowy as ubyte
lowy=LowestFCostSquareY
CheckSquare(lowx+1,lowy,targetx,targety,lowx,lowy)
CheckSquare(lowx-1,lowy,targetx,targety,lowx,lowy)
CheckSquare(lowx,lowy+1,targetx,targety,lowx,lowy)
CheckSquare(lowx,lowy-1,targetx,targety,lowx,lowy)
if path<>found then
AddToClosedList(lowx,lowy)
end if

end while

If path = found then
'Print "path was found"
If CreatePath(startx , starty , targetx ,targety)<>1 then
Return CantCreatePathError
End if

Return 1
End if

return 0
End Function

Function CheckSquare(squarex as integer,squarey as integer,targetx as integer,targety as integer,originalx as integer,originaly as integer) as UByte
if squarex>-1 then
if squarex<32 then
if squarey>-1 then
if squarey<24 then

'pathfindmessage("Check square:"+STR(squarex)+" "+STR(squarey))
If OnClosedList(squarex,squarey)=0 then
'pathfindmessage("not on closed list")
If OnOpenList(squarex,squarey)=0 then
'pathfindmessage("not on open list")

If squarex=targetx And squarey=targety then
path = found
End if

HCost(squarex,squarey)=GetHCost(squarex,squarey,targetx,targety)

AddToOpenList(squarex,squarey,originalx,originaly)

If path=found then
SquareParentX(squarex,squarey)=originalx
SquareParentY(squarex,squarey)=originaly
'Print "path is found"
AddToClosedList(squarex,squarey)
End if


End if
End if
End if
End if
End if
end if
End Function


Function GetHCost(squarex as integer,squarey as integer,targetx as integer,targety as integer) as integer
Return (Abs(squarex-targetx)+Abs(squarey-targety))
End Function

Function OnOpenList(squarex as Integer, squarey as Integer) as integer
if SquareState(squarex,squarey)=1 then
return 1
end if
return 0
end function
Function OnClosedList(squarex as Integer, squarey as Integer) as integer
if SquareState(squarex,squarey)=2 then
return 1
end if
return 0
end function

Function AddToOpenList(squarex as Integer, squarey as Integer,parx as integer, pary as integer)
SquareParentX(squarex,squarey)=parx
SquareParentY(squarex,squarey)=pary
numberofopenlistitems=numberofopenlistitems+1
If HCost(squarex,squarey)<HCost(LowestFCostSquareX,LowestFCostSquareY) then
LowestFCostSquareX=squarex
LowestFCostSquareY=squarey
End if
SquareState(squarex,squarey)=1
Print at squarey,squarex;"O"
end function

Function AddToClosedList(squarex as Integer, squarey as Integer)
if LowestFCostSquareX=squarex then
if LowestFCostSquareY=squarey then
Dim dist as Integer
dim chosenX as integer
Dim chosenY as integer
chosenX=-1
chosenY=-1

dist=9999
for x=0 to 32
for y=0 to 24
if OnOpenList(x,y) then
If HCost(x,y)<dist then
dist=HCost(x,y)
chosenX=x
chosenY=y
end if
End if
Next
Next

If chosenX>-1 then
LowestFCostSquareX=chosenX
LowestFCostSquareY=chosenY
End if

end if
end if
if SquareState(squarex,squarey)=1 then
numberofopenlistitems=numberofopenlistitems-1
end if
SquareState(squarex,squarey)=2
Print at squarey,squarex;"C"
end function

Function AddToPath(squarex as Integer, squarey as Integer)
Print at squarey,squarex;"P"
end function


Function CreatePath(StartX as integer,StartY as integer,TargetX as integer,TargetY as integer) as integer
PathBlockedByPerson=0
PathBlocker=0
dim PathCreated as Ubyte
dim ParX as Integer
dim ParY as Integer
StepsOnPath=StepsOnPath+1
PathToWalkX(StepsOnPath)=TargetX
PathToWalkY(StepsOnPath)=TargetY
ParX=PathToWalkX(StepsOnPath)
ParY=PathToWalkY(StepsOnPath)
While PathCreated=0
Dim NewParX as integer
Dim NewParY as integer
NewParX=SquareParentX(ParX,ParY)
NewParY=SquareParentY(ParX,ParY)
ParX=NewParX
ParY=NewParY
AddToPath(ParX,ParY)
StepsOnPath=StepsOnPath+1
If StepsOnPath=StepsOnPath>254  then
Return 2
End if
PathToWalkX(StepsOnPath)=ParX
PathToWalkY(StepsOnPath)=ParY
If PathToWalkX(StepsOnPath)=StartX And PathToWalkY(StepsOnPath)=StartY  then
exit while
End if

Wend
Return 1
End Function


function ClearPath()
for x=0 to 32
for y=0 to 24
SquareState(x,y)=0
SquareParentX(x,y)=0
SquareParentY(x,y)=0
HCost(x,y)=0
next
next
'for x=0 to 768
'PathToWalkX(x)=0
'PathToWalkY(x)=0
'next
StepsOnPath=0
PathBlockedByPerson=0
PathBlocker=0
numberofopenlistitems=0

End Function

Dim pathfindprint as ubyte

Function pathfindmessage(msg as string)
Print at pathfindprint,0 ; msg
pathfindprint=pathfindprint+1
if pathfindprint>24 then
pathfindprint=0
end if
end function
Border 5
FindPath(0,10,10,0)
FindPath(0,10,31,23)
FindPath(31,23,0,0)

Print this item

  SLS <reg>
Posted by: britlion - 04-22-2012, 11:25 PM - Forum: Help & Support - Replies (2)

Technically undocumented - but the assembler doesn't support the shift instruction SLS. Unfortunately, not being documented, it doesn't have an official name - I've seen the same instructions called "SLL" as well - and shift left logical does seem to match with shift right logical.

Have a look at:
<!-- m --><a class="postlink" href="http://www.ime.usp.br/~einar/z80table/">http://www.ime.usp.br/~einar/z80table/</a><!-- m -->


In particular CB30 - CB37


That table is quite useful, actually Smile

Print this item