Hey,
This is my old Blitz3d code translated to GLBasic. I used it just to learn GLBasic. Additionally there's attached a compiled version with a few examples (press LMB or F9 to B&W/Color mode, RMB or F10 to "loadingstrips FX" ON/OFF and SPACE or F11 to load next ZX screen).
// --------------------------------- //
// Project: ZX Spectrum Screen
// Start: Monday, October 17, 2011
// IDE Version: 10.118
SETCURRENTDIR("Media") // go to media files
GLOBAL VIDRAM = 16384 //videoram
GLOBAL VIDATR = 22528 //attributes
GLOBAL ZXRAMbank[]
DIM ZXRAMbank[65536] //ZX memory image 16KB ROM + 48KB RAM
GLOBAL colortable[]
DIM colortable[16] //colors FOR WritePixelFast
MakeColors()
GLOBAL flashstate = TRUE
GLOBAL time = 250 // flash frq
GLOBAL oldTime
GLOBAL load = TRUE //loadingFX simulator
GLOBAL BWmode = FALSE
GLOBAL waitkey = 0
//------- demo --------
SETSCREEN 320,256,0
STARTDATA screens:
DATA "LuckyLucke.scr", "terrorpolis.scr", "ship.scr", "sen1.11.scr", "sen.scr", "knights.scr"
ENDDATA
GLOBAL scrCounter = 1, scrfile$
RESTORE screens
READ scrfile$
OpenSCR(scrfile$)
WHILE TRUE
ZXField()
IF waitkey > 0
waitkey = waitkey-1
ENDIF
MOUSESTATE mx, my, b1, b2
IF (KEY(67) = 1 OR b1 = 1) AND waitkey = 0 //KEY F9 = B/W / color mode
BWmode = NOT BWmode
waitkey = 10
IF BWmode = TRUE
MakeGrey()
ELSE
MakeColors()
ENDIF
ELSEIF (KEY(68) = 1 OR b2 = 1) AND waitkey = 0 //KEY F10 = border loading effect
load = 1 - load
waitkey = 10
ELSEIF (KEY(87) = 1 OR KEY(57) = 1) AND waitkey = 0 //KEY F10 = border loading effect
INC scrCounter
IF scrCounter > 6
scrCounter = 1
RESTORE screens
ENDIF
READ scrfile$
OpenSCR(scrfile$)
waitkey = 10
ENDIF
SHOWSCREEN
SLEEP 1
WEND
END
//---------------------
//.scr, .zx, .$c, .s 6912 AND 6929 are supported
FUNCTION OpenSCR: scrfile$, channel1=1
IF scrfile$<>"" AND (RIGHT$(scrfile$,4)=".scr" OR RIGHT$(scrfile$,3)=".zx" OR RIGHT$(scrfile$,2)=".s" OR RIGHT$(scrfile$,3)=".$c")
LOCAL sizefile=GETFILESIZE(scrfile$)
LOCAL screenfile = OPENFILE(channel1, scrfile$, 1)
IF sizefile = 6912
ReadBytes (channel1, 16384,6912)
ELSEIF sizefile = 6929
ReadBytes (channel1, 16384-17,6912)
ENDIF
CLOSEFILE 1
ENDIF
ENDFUNCTION
FUNCTION ReadBytes: chan, adres, lenght
LOCAL count, newDATA%
FOR count=0 TO lenght-1
READBYTE chan, newDATA%
ZXRAMbank[adres+count]=newDATA%
NEXT
ENDFUNCTION
//render ZX screen
FUNCTION ZXField:
LOCAL argb%
FlashEffect()
FOR y%=0 TO 255 STEP 2
IF load
argb = RND(10)
IF argb>5
IF BWmode=FALSE
argb = RGB(0,50,200)//blue strips
ELSE
argb = 5592405
ENDIF
ELSE
IF BWmode=FALSE
argb = RGB(200,200,40)//yellow strips
ELSE
argb = 0
ENDIF
ENDIF
ELSE
argb = 0
ENDIF
DRAWLINE 0,y, 320, y, argb
DRAWLINE 0,y+1, 320, y+1, argb
NEXT
DrawScreen(32, 32)
ENDFUNCTION
//get INK color
FUNCTION AttrInk: byte
RETURN bAND(byte,7)
ENDFUNCTION
//get PAPER color
FUNCTION AttrPaper: byte
RETURN bAND(ASR (byte,3),7)
ENDFUNCTION
//get BRIGHT attribute
FUNCTION AttrBright: byte
RETURN bAND(byte,64)
ENDFUNCTION
//get FLASH attribute
FUNCTION AttrFlash: byte
RETURN bAND(byte,128)
ENDFUNCTION
//video processor ;)
//x,y - screen coordinates (+32 pixels for border)
FUNCTION DrawScreen: X=32, Y=32
LOCAL Xpixel, Ypixel, bblok, bajt, attr, brightcolor, inkcolor, paperColor, flashcolor, temp, video, blok, at, bat, b, l
Ypixel = Y
FOR blok = 0 TO 2
bblok = blok * 256
FOR at = 0 TO 7
bat = at*32
FOR l = 0+at*32+blok*2048 TO 2047+blok*2048 STEP 256
Xpixel = X
FOR b = 0 TO 31
bajt = ZXRAMbank[VIDRAM+b+l]
attr = ZXRAMbank[VIDATR+b+bat+bblok]
brightcolor = ASR (AttrBright (attr), 3)
// inkcolor = 7
// paperColor = 0
inkcolor = AttrInk (attr) + brightcolor
paperColor = AttrPaper (attr) + brightcolor
flashcolor = AttrFlash (attr)
IF flashcolor=128 AND flashstate = TRUE
temp=inkcolor
inkcolor=paperColor
paperColor=temp
ENDIF
video = bAND(bajt,128) //;1
SELECT video
CASE 128
SETPIXEL Xpixel,Ypixel, colortable[inkcolor]
CASE 0
SETPIXEL Xpixel,Ypixel, colortable[paperColor]
ENDSELECT
Xpixel = Xpixel + 1
video = bAND(bajt,64) //;2
SELECT video
CASE 64
SETPIXEL Xpixel,Ypixel, colortable[inkcolor]
CASE 0
SETPIXEL Xpixel,Ypixel, colortable[paperColor]
ENDSELECT
Xpixel = Xpixel + 1
video = bAND(bajt,32) //;3
SELECT video
CASE 32
SETPIXEL Xpixel,Ypixel, colortable[inkcolor]
CASE 0
SETPIXEL Xpixel,Ypixel, colortable[paperColor]
ENDSELECT
Xpixel = Xpixel + 1
video = bAND(bajt,16) //;4
SELECT video
CASE 16
SETPIXEL Xpixel,Ypixel, colortable[inkcolor]
CASE 0
SETPIXEL Xpixel,Ypixel, colortable[paperColor]
ENDSELECT
Xpixel = Xpixel + 1
video = bAND(bajt,8) //;5
SELECT video
CASE 8
SETPIXEL Xpixel,Ypixel, colortable[inkcolor]
CASE 0
SETPIXEL Xpixel,Ypixel, colortable[paperColor]
ENDSELECT
Xpixel = Xpixel + 1
video = bAND(bajt,4) //;6
SELECT video
CASE 4
SETPIXEL Xpixel,Ypixel, colortable[inkcolor]
CASE 0
SETPIXEL Xpixel,Ypixel, colortable[paperColor]
ENDSELECT
Xpixel = Xpixel + 1
video = bAND(bajt,2) //;7
SELECT video
CASE 2
SETPIXEL Xpixel,Ypixel, colortable[inkcolor]
CASE 0
SETPIXEL Xpixel,Ypixel, colortable[paperColor]
ENDSELECT
Xpixel = Xpixel + 1
video = bAND(bajt,1) //;8
SELECT video
CASE 1
SETPIXEL Xpixel,Ypixel, colortable[inkcolor]
CASE 0
SETPIXEL Xpixel,Ypixel, colortable[paperColor]
ENDSELECT
Xpixel = Xpixel + 1
NEXT
Ypixel = Ypixel + 1
NEXT
NEXT
NEXT
ENDFUNCTION
//FLASH timing
FUNCTION FlashEffect:
IF GETTIMERALL() > oldTime + time
IF flashstate = TRUE
flashstate = FALSE
oldTime=GETTIMERALL()
ELSE
flashstate = TRUE
oldTime=GETTIMERALL()
ENDIF
ENDIF
ENDFUNCTION
//ZXGreyscale
FUNCTION MakeGrey:
FOR k=0 TO 15
colortable[k] = Grey(colortable[k])
NEXT
ENDFUNCTION
//ZXSpectrum colors
FUNCTION MakeColors:
colortable[0] = RGB(0,0,0) //;BLACK
colortable[1] = RGB(0,10,120) //;BLUE
colortable[2] = RGB(200,20,20) //;RED
colortable[3] = RGB(200,40,200) //;MAGENTA
colortable[4] = RGB(20,200,20) //;GREEN
colortable[5] = RGB(40,200,200) //;CYAN
colortable[6] = RGB(200,200,40) //;YELLOW
colortable[7] = RGB(200,200,200) //;WHITE
colortable[8] = RGB(1,1,1) //;BLACK + BRIGHT
colortable[9] = RGB(0,20,200) //;BLUE + BRIGHT
colortable[10] = RGB(255,40,40) //;RED + BRIGHT
colortable[11] = RGB(255,80,255) //;MAGENTA + BRIGHT
colortable[12] = RGB(40,255,40) //;GREEN + BRIGHT
colortable[13] = RGB(80,255,255) //;CYAN + BRIGHT
colortable[14] = RGB(255,255,80) //;YELLOW + BRIGHT
colortable[15] = RGB(255,255,255) //;WHITE + BRIGHT
ENDFUNCTION
FUNCTION Grey: rgb1
red1=bAND(ASR(rgb1,16), 255)
green1=bAND(ASR(rgb1,8),255)
blue1=bAND(rgb1,255)
//simple grayscale
gray=(red1+green1+blue1)/3
//greyscale by Peter Scheutz
//gray=red1*0.3 + green1*.059 + blue1*0.11
red1=gray
green1=gray
blue1=gray
RETURN RGB(red1, green1, blue1)
ENDFUNCTION
Regards,
Michal
[attachment deleted by admin]
Very cool !!!!!!!!!!!!!!!!
AND LOADING FX TOO!!!!
;) 8)
[attachment deleted by admin]
Very cool. I still love the ZX Spectrum and have mine safe in a box to preserve for future generations. :D
Those were happy days with ZX Spectrum ;).
I'm still learning GLBasic. It's really awesome basic dialect.
This is modified version of DrawScreen function. Now it uses MEM2SPRITE technique and it's much faster than previous version. Now it works at decent speed on my Galaxy S.
FUNCTION DrawScreen: X=32, Y=32
LOCAL Xpixel, Ypixel, bblok, bajt, attr, brightcolor, inkcolor, paperColor, flashcolor, temp, video, blok, at, bat, b, l
DIM pix%[256*256]
Ypixel = Y-32
FOR blok = 0 TO 2
bblok = blok * 256
FOR at = 0 TO 7
bat = at*32
FOR l = 0+at*32+blok*2048 TO 2047+blok*2048 STEP 256
Xpixel = X-32
FOR b = 0 TO 31
bajt = ZXRAMbank[VIDRAM+b+l]
attr = ZXRAMbank[VIDATR+b+bat+bblok]
brightcolor = ASR (AttrBright (attr), 3)
// inkcolor = 7
// paperColor = 0
inkcolor = AttrInk (attr) + brightcolor
paperColor = AttrPaper (attr) + brightcolor
flashcolor = AttrFlash (attr)
IF flashcolor=128 AND flashstate = TRUE
temp=inkcolor
inkcolor=paperColor
paperColor=temp
ENDIF
video = bAND(bajt,128) //;1
SELECT video
CASE 128
//SETPIXEL Xpixel,Ypixel, colortable[inkcolor]
pix[Xpixel + Ypixel*256] = bOR(colortable[inkcolor], ASL(0x00ffffff,24))//colortable[inkcolor]+ 0xff000000
CASE 0
//SETPIXEL Xpixel,Ypixel, colortable[paperColor]
pix[Xpixel + Ypixel*256] = bOR(colortable[paperColor], ASL(0x00ffffff, 24))//colortable[paperColor]+ 0xff000000
ENDSELECT
Xpixel = Xpixel + 1
video = bAND(bajt,64) //;2
SELECT video
CASE 64
//SETPIXEL Xpixel,Ypixel, colortable[inkcolor]
pix[Xpixel + Ypixel*256] = bOR(colortable[inkcolor], ASL(0x00ffffff,24))//colortable[inkcolor]+ 0xff000000
CASE 0
//SETPIXEL Xpixel,Ypixel, colortable[paperColor]
pix[Xpixel + Ypixel*256] = bOR(colortable[paperColor], ASL(0x00ffffff, 24))//colortable[paperColor]+ 0xff000000
ENDSELECT
Xpixel = Xpixel + 1
video = bAND(bajt,32) //;3
SELECT video
CASE 32
//SETPIXEL Xpixel,Ypixel, colortable[inkcolor]
pix[Xpixel + Ypixel*256] = bOR(colortable[inkcolor], ASL(0x00ffffff,24))//colortable[inkcolor]+ 0xff000000
CASE 0
//SETPIXEL Xpixel,Ypixel, colortable[paperColor]
pix[Xpixel + Ypixel*256] = bOR(colortable[paperColor], ASL(0x00ffffff, 24))//colortable[paperColor]+ 0xff000000
ENDSELECT
Xpixel = Xpixel + 1
video = bAND(bajt,16) //;4
SELECT video
CASE 16
//SETPIXEL Xpixel,Ypixel, colortable[inkcolor]
pix[Xpixel + Ypixel*256] = bOR(colortable[inkcolor], ASL(0x00ffffff,24))//colortable[inkcolor]+ 0xff000000
CASE 0
//SETPIXEL Xpixel,Ypixel, colortable[paperColor]
pix[Xpixel + Ypixel*256] = bOR(colortable[paperColor], ASL(0x00ffffff, 24))//colortable[paperColor]+ 0xff000000
ENDSELECT
Xpixel = Xpixel + 1
video = bAND(bajt,8) //;5
SELECT video
CASE 8
//SETPIXEL Xpixel,Ypixel, colortable[inkcolor]
pix[Xpixel + Ypixel*256] = bOR(colortable[inkcolor], ASL(0x00ffffff,24))//colortable[inkcolor]+ 0xff000000
CASE 0
//SETPIXEL Xpixel,Ypixel, colortable[paperColor]
pix[Xpixel + Ypixel*256] = bOR(colortable[paperColor], ASL(0x00ffffff, 24))//colortable[paperColor]+ 0xff000000
ENDSELECT
Xpixel = Xpixel + 1
video = bAND(bajt,4) //;6
SELECT video
CASE 4
//SETPIXEL Xpixel,Ypixel, colortable[inkcolor]
pix[Xpixel + Ypixel*256] = bOR(colortable[inkcolor], ASL(0x00ffffff,24))//colortable[inkcolor]+ 0xff000000
CASE 0
//SETPIXEL Xpixel,Ypixel, colortable[paperColor]
pix[Xpixel + Ypixel*256] = bOR(colortable[paperColor], ASL(0x00ffffff, 24))//colortable[paperColor]+ 0xff000000
ENDSELECT
Xpixel = Xpixel + 1
video = bAND(bajt,2) //;7
SELECT video
CASE 2
//SETPIXEL Xpixel,Ypixel, colortable[inkcolor]
pix[Xpixel + Ypixel*256] = bOR(colortable[inkcolor], ASL(0x00ffffff,24))//colortable[inkcolor]+ 0xff000000
CASE 0
//SETPIXEL Xpixel,Ypixel, colortable[paperColor]
pix[Xpixel + Ypixel*256] = bOR(colortable[paperColor], ASL(0x00ffffff, 24))//colortable[paperColor]+ 0xff000000
ENDSELECT
Xpixel = Xpixel + 1
video = bAND(bajt,1) //;8
SELECT video
CASE 1
//SETPIXEL Xpixel,Ypixel, colortable[inkcolor]
pix[Xpixel + Ypixel*256] = bOR(colortable[inkcolor], ASL(0x00ffffff,24))//colortable[inkcolor]+ 0xff000000
CASE 0
//SETPIXEL Xpixel,Ypixel, colortable[paperColor]
pix[Xpixel + Ypixel*256] = bOR(colortable[paperColor], ASL(0x00ffffff, 24))//colortable[paperColor]+ 0xff000000
ENDSELECT
Xpixel = Xpixel + 1
NEXT
Ypixel = Ypixel + 1
NEXT
NEXT
NEXT
MEM2SPRITE(pix[], 1, 256, 256)
DRAWSPRITE 1, 32, 32
ENDFUNCTION
Regards,
Michal
A Spectrum style framework would be cool - if that is a logical next step...
Commands to draw UDGs and text with attributes etc.
It's a shame there is no pitch commands for sound in GLBasic so it would make it hard or impossible to make a BEEP command. :)
There was a routine posted a few months ago that does just that Caff; IIRC it was called BEEP too.
BTW Nice routine Mikele :)
Quote from: Mikele on 2011-Oct-19
Those were happy days with ZX Spectrum ;).
I'm still learning GLBasic. It's really awesome basic dialect.
This is modified version of DrawScreen function. Now it uses MEM2SPRITE technique and it's much faster than previous version. Now it works at decent speed on my Galaxy S.
FUNCTION DrawScreen: X=32, Y=32
LOCAL Xpixel, Ypixel, bblok, bajt, attr, brightcolor, inkcolor, paperColor, flashcolor, temp, video, blok, at, bat, b, l
DIM pix%[256*256]
Ypixel = Y-32
FOR blok = 0 TO 2
bblok = blok * 256
FOR at = 0 TO 7
bat = at*32
FOR l = 0+at*32+blok*2048 TO 2047+blok*2048 STEP 256
Xpixel = X-32
FOR b = 0 TO 31
bajt = ZXRAMbank[VIDRAM+b+l]
attr = ZXRAMbank[VIDATR+b+bat+bblok]
brightcolor = ASR (AttrBright (attr), 3)
// inkcolor = 7
// paperColor = 0
inkcolor = AttrInk (attr) + brightcolor
paperColor = AttrPaper (attr) + brightcolor
flashcolor = AttrFlash (attr)
IF flashcolor=128 AND flashstate = TRUE
temp=inkcolor
inkcolor=paperColor
paperColor=temp
ENDIF
video = bAND(bajt,128) //;1
SELECT video
CASE 128
//SETPIXEL Xpixel,Ypixel, colortable[inkcolor]
pix[Xpixel + Ypixel*256] = bOR(colortable[inkcolor], ASL(0x00ffffff,24))//colortable[inkcolor]+ 0xff000000
CASE 0
//SETPIXEL Xpixel,Ypixel, colortable[paperColor]
pix[Xpixel + Ypixel*256] = bOR(colortable[paperColor], ASL(0x00ffffff, 24))//colortable[paperColor]+ 0xff000000
ENDSELECT
Xpixel = Xpixel + 1
video = bAND(bajt,64) //;2
SELECT video
CASE 64
//SETPIXEL Xpixel,Ypixel, colortable[inkcolor]
pix[Xpixel + Ypixel*256] = bOR(colortable[inkcolor], ASL(0x00ffffff,24))//colortable[inkcolor]+ 0xff000000
CASE 0
//SETPIXEL Xpixel,Ypixel, colortable[paperColor]
pix[Xpixel + Ypixel*256] = bOR(colortable[paperColor], ASL(0x00ffffff, 24))//colortable[paperColor]+ 0xff000000
ENDSELECT
Xpixel = Xpixel + 1
video = bAND(bajt,32) //;3
SELECT video
CASE 32
//SETPIXEL Xpixel,Ypixel, colortable[inkcolor]
pix[Xpixel + Ypixel*256] = bOR(colortable[inkcolor], ASL(0x00ffffff,24))//colortable[inkcolor]+ 0xff000000
CASE 0
//SETPIXEL Xpixel,Ypixel, colortable[paperColor]
pix[Xpixel + Ypixel*256] = bOR(colortable[paperColor], ASL(0x00ffffff, 24))//colortable[paperColor]+ 0xff000000
ENDSELECT
Xpixel = Xpixel + 1
video = bAND(bajt,16) //;4
SELECT video
CASE 16
//SETPIXEL Xpixel,Ypixel, colortable[inkcolor]
pix[Xpixel + Ypixel*256] = bOR(colortable[inkcolor], ASL(0x00ffffff,24))//colortable[inkcolor]+ 0xff000000
CASE 0
//SETPIXEL Xpixel,Ypixel, colortable[paperColor]
pix[Xpixel + Ypixel*256] = bOR(colortable[paperColor], ASL(0x00ffffff, 24))//colortable[paperColor]+ 0xff000000
ENDSELECT
Xpixel = Xpixel + 1
video = bAND(bajt,8) //;5
SELECT video
CASE 8
//SETPIXEL Xpixel,Ypixel, colortable[inkcolor]
pix[Xpixel + Ypixel*256] = bOR(colortable[inkcolor], ASL(0x00ffffff,24))//colortable[inkcolor]+ 0xff000000
CASE 0
//SETPIXEL Xpixel,Ypixel, colortable[paperColor]
pix[Xpixel + Ypixel*256] = bOR(colortable[paperColor], ASL(0x00ffffff, 24))//colortable[paperColor]+ 0xff000000
ENDSELECT
Xpixel = Xpixel + 1
video = bAND(bajt,4) //;6
SELECT video
CASE 4
//SETPIXEL Xpixel,Ypixel, colortable[inkcolor]
pix[Xpixel + Ypixel*256] = bOR(colortable[inkcolor], ASL(0x00ffffff,24))//colortable[inkcolor]+ 0xff000000
CASE 0
//SETPIXEL Xpixel,Ypixel, colortable[paperColor]
pix[Xpixel + Ypixel*256] = bOR(colortable[paperColor], ASL(0x00ffffff, 24))//colortable[paperColor]+ 0xff000000
ENDSELECT
Xpixel = Xpixel + 1
video = bAND(bajt,2) //;7
SELECT video
CASE 2
//SETPIXEL Xpixel,Ypixel, colortable[inkcolor]
pix[Xpixel + Ypixel*256] = bOR(colortable[inkcolor], ASL(0x00ffffff,24))//colortable[inkcolor]+ 0xff000000
CASE 0
//SETPIXEL Xpixel,Ypixel, colortable[paperColor]
pix[Xpixel + Ypixel*256] = bOR(colortable[paperColor], ASL(0x00ffffff, 24))//colortable[paperColor]+ 0xff000000
ENDSELECT
Xpixel = Xpixel + 1
video = bAND(bajt,1) //;8
SELECT video
CASE 1
//SETPIXEL Xpixel,Ypixel, colortable[inkcolor]
pix[Xpixel + Ypixel*256] = bOR(colortable[inkcolor], ASL(0x00ffffff,24))//colortable[inkcolor]+ 0xff000000
CASE 0
//SETPIXEL Xpixel,Ypixel, colortable[paperColor]
pix[Xpixel + Ypixel*256] = bOR(colortable[paperColor], ASL(0x00ffffff, 24))//colortable[paperColor]+ 0xff000000
ENDSELECT
Xpixel = Xpixel + 1
NEXT
Ypixel = Ypixel + 1
NEXT
NEXT
NEXT
MEM2SPRITE(pix[], 1, 256, 256)
DRAWSPRITE 1, 32, 32
ENDFUNCTION
Regards,
Michal
Make a full ZX emulator with GLB... ;)
see the SFXR example. It just creates a wav file on the fly and loads that. Not really great, but it works.
I have plans for a better sound engine that allows generation of synthetic sounds. But it's at the bottom of the todo.
I would imagine that the tone on the spectrum is just 256 separate pitches, maybe use SFXR to create these and load them into an array?
Quote from: Hark0 on 2011-Oct-20
Make a full ZX emulator with GLB... ;)
Hehe. Honestly I wrote partially working Z80 processor simulator years ago (I should have blitz source somewhere). But it could be difficult to merge all these things together - I'm just a weekend programmer ;).
Quote from: Kitty Hello on 2011-Oct-20
see the SFXR example. It just creates a wav file on the fly and loads that. Not really great, but it works.
I'll take a look at that. I'd like to code an AY player ;).
I did have a look about for a z80 core written in basic and noticed that there was a full spectrum emulator written in basic a while back but no source code available and then thought about sound and quickly forgot about even thinking about that project :(
But a nice bit of code there
Cool =D
I done a similar program in blitz which loaded the screens from SNA & Z80 snapshots. It loaded the screens in the same way as the spectrum so you see them being generated like a real speccy, first the pixels followed by the colour. Never thought about doing the loading border though so hats off for that :enc:
Does this help?
http://freestuff.grok.co.uk/vbspec/
=)
A ZX Spectrum emulator in VB, class! Also crazy.
Ah man if only I was in Uni again and had all the time in the world (assuming you ignore lectures like I did) to convert it to GLB. Unfortuantly you have to worry about the legality of including the ROMs (eg. +2 ROM).
Even if there is a way round the machine ROMs you have the problem of the game ROMs. You could of course use freeware Spectrum games rather than proper game roms (dodgy ground) and there is a similar list of Spectrum games (expensive!) on the iOS app store, but that much effort with potentially an un-sellable product equals me wishing I was in Uni again :)
Cheers
Amstrad freely released the Spectrum BIOS ROMs to the public domain, so no worries there and World Of Spectrum has been given free reign by IP owners to share Spectrum games - all games on World Of Spectrum are legit and have written permission to be on there (where possible). Certain companies (like RARE and ODIN IIRC) have refused their games to be made available, so they don't appear on WOS.
So no legal minefields here really. :)
Ang on. So you are saying proper full priced games (eg. Cybernoid) on WOS have been given permission to be used, as well as the game ROMS?
Hmm. Interesting. Note that Elite systems have a few Spectrum games going on the iOS store and they charge quite a bit. Like a couple of quid a throw.
So do these permissions allow you to sell the game on? Or do they force freeware releases? Perhaps Elite have an agreement.
It's an interesting problem how you get around it if cannot be sold. Perhaps could say the emulator costs money, but then you can add games to it from WOS or yourself using iTunes.
I'm almost itchy to give it a go, but I'm betting would be some project to convert to GLB *and* get it to work well on a mobile device. And then you would have to make absolutely sure all the legal bits are properly dotted and underlined etc.
Main thing for me is getting it to work properly on a touchscreen no-button device (like an iPhone). I haven't seen anything like it yet that I like. Anything with onscreen controls (those Namcom joysticks and fire buttons for example) tend to suck like no tomorrow.
Still it is very interesting....
Cheers
I just had a look on Elite systems site & took a peek at "Auf Wiedersehen Monty: ZX Spectrum HD", the HD part made me giggle then I saw a box at the side stating
Rated 9+ for the following:
Infrequent/Mild Horror/Fear Themes
Infrequent/Mild Cartoon or Fantasy Violence
Infrequent/Mild Realistic Violence
That done it for me, my sides have just stopped aching from the laughter.
Only way I think they can charge is for the emulator or such to run the game, it's not made clear.
I also noticed its a 19.5MB download :blink:
Unless you contact the IP owner and get permission, you probably can't sell on speccy games. ELITE owns the rights to loads of Speccy classics nowadays.
I would still like know where the HD in "Auf Wiedersehen Monty: ZX Spectrum HD" is, looking at the screenshot on the site
http://itunes.apple.com/gb/app/auf-wiedersehen-monty-zx-spectrum/id416365247?mt=8 (http://itunes.apple.com/gb/app/auf-wiedersehen-monty-zx-spectrum/id416365247?mt=8)
it looks surprisingly identical to the one on WoS
http://www.worldofspectrum.org/infoseekid.cgi?id=0000328 (http://www.worldofspectrum.org/infoseekid.cgi?id=0000328)
:D
HD is bandied around far too readily these days. That's just taking the piss.
I would settle for even that z80 core being ported to GLB, imagine the fun that could be had with a working core :)
Elite have got agreement with the respective publishers/programmers for the games in their emulator packs. Basically if you ever wrote a spectrum game and it was half decent you can get it included in a pack and still get paid for it!! It really is money for old rope.
Spectaculator has also been ported to IOS as well but unless you are jailbroken then there is no way of adding any extra games and the offering is pretty poor at the moment.
People that create/program emulators quite frankly amaze me. I can break down game logic or apps like a paint program, word processor etc but an emulator I would not have a clue where to begin. Things like WinUAE with all the custom chips & such, also MAME & MESS with more different configurations then I can count lol.
I take my hat off to the people that create such software :nw:
Quote from: fuzzy70 on 2011-Oct-26
I would still like know where the HD in "Auf Wiedersehen Monty: ZX Spectrum HD" is, looking at the screenshot on the site
http://itunes.apple.com/gb/app/auf-wiedersehen-monty-zx-spectrum/id416365247?mt=8 (http://itunes.apple.com/gb/app/auf-wiedersehen-monty-zx-spectrum/id416365247?mt=8)
it looks surprisingly identical to the one on WoS
http://www.worldofspectrum.org/infoseekid.cgi?id=0000328 (http://www.worldofspectrum.org/infoseekid.cgi?id=0000328)
:D
Hmm, I have real ZX Spectrum - actually it's a clone (Timex 2048) with extended RAM (144 kb) compatible with ZX128, AY generator (I made it at secondary school) + CF disk but I've bought a few gamepacks from Elite and I'm really satisfied with most of the games. It's nice to have Robin of The Wood or Laser Squad on my iPad. Yes - using HD in the title of the app is a kind of advertising but I'm happy that the games look as should (256x192 pixels 15 colors etc.).
Quote
Does this help?
http://freestuff.grok.co.uk/vbspec/
Thanks for the link. If I remember correctly I have two different sources of Z80 procesor emulator (blitz and C source) so maybe someday I'll try to make it in GLB.
public domain!? So it's legal to rip the levels?
Quote from: Kitty Hello on 2011-Oct-26
public domain!? So it's legal to rip the levels?
Nope!
Just because something is in the public domain, doesn't mean it has no copyright - the IP owner still retains this and thusly all graphics, level data and other media, unless clearly stated otherwise.
Hmm. So how about an emulator that then allows you to download a game from WOS, or possibly copy your own files into the app via the usual iTunes upload method? Would that be legal? I'm pretty sure a C64 emulator fell foul of Apple with this method years ago, but don't know how it would stand now. It's pretty much to do with Apples idea of not allowing an app that allows a download to allow it to function differently. But on the other hand I thought that covered things like Adobe Air and the like and thats all ok now apparently...
Cheers
You should be able to download any game from WOS and run it in/on your emulator without problem. As long as you don't disassemble the code, rip the media or distribute commercially, all should be good.
Apple's T&Cs may disrupt this though, due to them being Apple.
Ah the c***s factor. Yeah that can hurt. Wouldn't want to spend months on this with apple screwing me at the end. I'm still smarting after bikini Rotaslider and that only took me a couple of days to do...
Cheers
so dont let apple screw you over and do a decent one for Android :) none of the spectrum emulators I have seen on there have been just right, they have all had issues one way or the other
What sort of issues did they have?
Cheers
I thought "Public Domain" means: everyone can do whatever they want with it. True shame.
Not quite sure its classed as "public domain" more a case of "freeware" which means the original owner retains all copyrights over the product. After all Mame is seen as public domain but you try and do something with the source and not follow the GPL and they will come down on you.
Been reading up on how to write a spectrum emulator and it seems once the core and display routines are sorted its pretty much impossible not to load the rom and get a (C) Sinclair Research appear on the screen. After that its just a case of hooking in things like keyboard, sound etc. If you break everything down and have a stable core then emulation is fairly easy if you are emulating a well documented system like the spectrum. Get a memory map and you are sorted
Just played more with GLB and ZX things... Now the loading effect has more sense - every "screen" is loaded ZX-like way - that means you can see how the loading is progressing (press SPACE to load quickly, LEFT mouse button to load next ZXscreen, RIGHT to toggle color/b&w mode). The timings aren't correct as in real ZX but it's just for fun (to be honest I learn GLB that way). Thanks to Amon's delta time code it's still working with similar speed on my Galaxy S. I'm thinking about adding loading sounds.
// --------------------------------- //
// Project: ZX Spectrum Screen
// Start: Monday, October 17, 2011
// IDE Version: 10.118
SETCURRENTDIR("Media") // go to media files
GLOBAL VIDRAM = 16384 //videoram
GLOBAL VIDATR = 22528 //attributes
GLOBAL ZXRAMbank[]
DIM ZXRAMbank[65536] //ZX memory image 16KB ROM + 48KB RAM
GLOBAL SCREENbufor[]
DIM SCREENbufor[6912]
GLOBAL colortable[]
DIM colortable[16] //colors FOR WritePixelFast
MakeColors()
GLOBAL flashstate = TRUE
GLOBAL time = 350 // flash frq
GLOBAL oldTime
GLOBAL load = TRUE //loadingFX simulator
GLOBAL BWmode = FALSE
GLOBAL waitkey = 0
//------- demo --------
SETSCREEN 320,256, 0//320,256,0
LIMITFPS 50
STARTDATA screens:
DATA "LuckyLucke.scr", "terrorpolis.scr", "ship.scr", "sen1.11.scr", "sen.scr", "knights.scr", "miasto.scr", "space2.scr"
ENDDATA
GLOBAL scrCounter = 1, scrfile$
RESTORE screens
READ scrfile$
GLOBAL is_loading = FALSE
GLOBAL adres_count = 0
GLOBAL game_delta = 0
GLOBAL ubermultiplyer=0
GLOBAL dt AS DeltaTimer
dt.InitDelta()
dt.SetDeltaFPS(50.0)
//OpenSCR(scrfile$)
PrepareLoad(scrfile$)
WHILE TRUE
ALPHAMODE -1
ZXField()
dt.UpdateDelta()
IF waitkey > 0
waitkey = waitkey-1
ENDIF
MOUSESTATE mx, my, b1, b2
IF is_loading
LoadSCR()
ENDIF
IF (KEY(67) = 1 OR b2 = 1) AND waitkey = 0 //KEY F9 = B/W / color mode
BWmode = NOT BWmode
waitkey = 10
IF BWmode = TRUE
MakeGrey()
ELSE
MakeColors()
ENDIF
ELSEIF (KEY(87) = 1 OR b1 = 1) AND waitkey = 0 AND is_loading=FALSE
INC scrCounter
IF scrCounter > 8
scrCounter = 1
RESTORE screens
ENDIF
READ scrfile$
PrepareLoad(scrfile$)
// OpenSCR(scrfile$)
waitkey = 10
ENDIF
IF (KEY(57)) = 1
ubermultiplyer=1
ELSE
ubermultiplyer=0
ENDIF
SHOWSCREEN
SLEEP 1
WEND
END
//---------------------
FUNCTION ResetZXVideoRAM:
LOCAL count
FOR count=0 TO 6143
ZXRAMbank[16384+count]=0
NEXT
FOR count=6144 TO 6911
ZXRAMbank[16384+count]=56
NEXT
ENDFUNCTION
//.scr, .zx, .$c, .s 6912 AND 6929 are supported
FUNCTION OpenSCR: scrfile$, channel1=1
IF scrfile$<>"" AND (RIGHT$(scrfile$,4)=".scr" OR RIGHT$(scrfile$,3)=".zx" OR RIGHT$(scrfile$,2)=".s" OR RIGHT$(scrfile$,3)=".$c")
LOCAL sizefile=GETFILESIZE(scrfile$)
LOCAL screenfile = OPENFILE(channel1, scrfile$, 1)
IF sizefile = 6912
ReadBytes (channel1, 16384,6912)
ELSEIF sizefile = 6929
ReadBytes (channel1, 16384-17,6912)
ENDIF
CLOSEFILE 1
ENDIF
ENDFUNCTION
FUNCTION ReadBytes: chan, adres, lenght
LOCAL count, newDATA%
FOR count=0 TO lenght-1
READBYTE chan, newDATA%
ZXRAMbank[adres+count]=newDATA%
NEXT
ENDFUNCTION
FUNCTION PrepareLoad: scrfile$, channel1=1
IF scrfile$<>"" AND (RIGHT$(scrfile$,4)=".scr" OR RIGHT$(scrfile$,3)=".zx" OR RIGHT$(scrfile$,2)=".s" OR RIGHT$(scrfile$,3)=".$c")
LOCAL sizefile=GETFILESIZE(scrfile$)
LOCAL screenfile = OPENFILE(channel1, scrfile$, 1)
LOCAL count, newDATA%
IF sizefile = 6912
FOR count=0 TO 6911
READBYTE channel1, newDATA%
SCREENbufor[count]=newDATA%
NEXT
ELSEIF sizefile = 6929
FOR count=0 TO 6928
READBYTE channel1, newDATA%
IF count>16
SCREENbufor[count]=newDATA%
ENDIF
NEXT
ENDIF
CLOSEFILE 1
is_loading = TRUE
adres_count = 0
ResetZXVideoRAM()
ENDIF
ENDFUNCTION
//.scr, .zx, .$c, .s 6912 AND 6929 are supported
FUNCTION LoadSCR: channel1=1
LOCAL kMax = 4
LOCAL multiplyer = INTEGER(game_delta)
IF multiplyer>1 THEN kMax=4*multiplyer
IF ubermultiplyer=1 THEN kMax=4*128
FOR k=0 TO kMax-1
IF (adres_count + k) < 6912
ZXRAMbank[16384 + adres_count + k] = SCREENbufor[0+adres_count + k]
ENDIF
NEXT
adres_count = adres_count + kMax
IF adres_count > 6911
is_loading = FALSE
ENDIF
ENDFUNCTION
//render ZX screen
FUNCTION ZXField:
LOCAL argb%
FlashEffect()
FOR y%=0 TO 255 STEP 2
IF is_loading
argb = RND(10)
IF argb>5
IF BWmode=FALSE
argb = RGB(0,50,200)//blue strips
ELSE
argb = 5592405
ENDIF
ELSE
IF BWmode=FALSE
argb = RGB(200,200,40)//yellow strips
ELSE
argb = RGB(200,200,200)
ENDIF
ENDIF
ELSE
argb = 0
ENDIF
DRAWLINE 0,y, 320, y, argb
DRAWLINE 0,y+1, 320, y+1, argb
NEXT
DrawScreen(32, 32)
ENDFUNCTION
//get INK color
FUNCTION AttrInk: byte
RETURN bAND(byte,7)
ENDFUNCTION
//get PAPER color
FUNCTION AttrPaper: byte
RETURN bAND(ASR (byte,3),7)
ENDFUNCTION
//get BRIGHT attribute
FUNCTION AttrBright: byte
RETURN bAND(byte,64)
ENDFUNCTION
//get FLASH attribute
FUNCTION AttrFlash: byte
RETURN bAND(byte,128)
ENDFUNCTION
//video processor ;)
//x,y - screen coordinates (+32 pixels for border)
FUNCTION DrawScreen: X=32, Y=32
LOCAL Xpixel, Ypixel, bblok, bajt, attr, brightcolor, inkcolor, paperColor, flashcolor, temp, video, blok, at, bat, b, l
DIM pix%[256*256]
Ypixel = Y-32
FOR blok = 0 TO 2
bblok = blok * 256
FOR at = 0 TO 7
bat = at*32
FOR l = 0+at*32+blok*2048 TO 2047+blok*2048 STEP 256
Xpixel = X-32
FOR b = 0 TO 31
bajt = ZXRAMbank[VIDRAM+b+l]
attr = ZXRAMbank[VIDATR+b+bat+bblok]
brightcolor = ASR (AttrBright (attr), 3)
// inkcolor = 7
// paperColor = 0
inkcolor = AttrInk (attr) + brightcolor
paperColor = AttrPaper (attr) + brightcolor
flashcolor = AttrFlash (attr)
IF flashcolor=128 AND flashstate = TRUE
temp=inkcolor
inkcolor=paperColor
paperColor=temp
ENDIF
video = bAND(bajt,128) //;1
SELECT video
CASE 128
//SETPIXEL Xpixel,Ypixel, colortable[inkcolor]
pix[Xpixel + Ypixel*256] = bOR(colortable[inkcolor], ASL(0x00ffffff,24))//colortable[inkcolor]+ 0xff000000
CASE 0
//SETPIXEL Xpixel,Ypixel, colortable[paperColor]
pix[Xpixel + Ypixel*256] = bOR(colortable[paperColor], ASL(0x00ffffff, 24))//colortable[paperColor]+ 0xff000000
ENDSELECT
Xpixel = Xpixel + 1
video = bAND(bajt,64) //;2
SELECT video
CASE 64
//SETPIXEL Xpixel,Ypixel, colortable[inkcolor]
pix[Xpixel + Ypixel*256] = bOR(colortable[inkcolor], ASL(0x00ffffff,24))//colortable[inkcolor]+ 0xff000000
CASE 0
//SETPIXEL Xpixel,Ypixel, colortable[paperColor]
pix[Xpixel + Ypixel*256] = bOR(colortable[paperColor], ASL(0x00ffffff, 24))//colortable[paperColor]+ 0xff000000
ENDSELECT
Xpixel = Xpixel + 1
video = bAND(bajt,32) //;3
SELECT video
CASE 32
//SETPIXEL Xpixel,Ypixel, colortable[inkcolor]
pix[Xpixel + Ypixel*256] = bOR(colortable[inkcolor], ASL(0x00ffffff,24))//colortable[inkcolor]+ 0xff000000
CASE 0
//SETPIXEL Xpixel,Ypixel, colortable[paperColor]
pix[Xpixel + Ypixel*256] = bOR(colortable[paperColor], ASL(0x00ffffff, 24))//colortable[paperColor]+ 0xff000000
ENDSELECT
Xpixel = Xpixel + 1
video = bAND(bajt,16) //;4
SELECT video
CASE 16
//SETPIXEL Xpixel,Ypixel, colortable[inkcolor]
pix[Xpixel + Ypixel*256] = bOR(colortable[inkcolor], ASL(0x00ffffff,24))//colortable[inkcolor]+ 0xff000000
CASE 0
//SETPIXEL Xpixel,Ypixel, colortable[paperColor]
pix[Xpixel + Ypixel*256] = bOR(colortable[paperColor], ASL(0x00ffffff, 24))//colortable[paperColor]+ 0xff000000
ENDSELECT
Xpixel = Xpixel + 1
video = bAND(bajt,8) //;5
SELECT video
CASE 8
//SETPIXEL Xpixel,Ypixel, colortable[inkcolor]
pix[Xpixel + Ypixel*256] = bOR(colortable[inkcolor], ASL(0x00ffffff,24))//colortable[inkcolor]+ 0xff000000
CASE 0
//SETPIXEL Xpixel,Ypixel, colortable[paperColor]
pix[Xpixel + Ypixel*256] = bOR(colortable[paperColor], ASL(0x00ffffff, 24))//colortable[paperColor]+ 0xff000000
ENDSELECT
Xpixel = Xpixel + 1
video = bAND(bajt,4) //;6
SELECT video
CASE 4
//SETPIXEL Xpixel,Ypixel, colortable[inkcolor]
pix[Xpixel + Ypixel*256] = bOR(colortable[inkcolor], ASL(0x00ffffff,24))//colortable[inkcolor]+ 0xff000000
CASE 0
//SETPIXEL Xpixel,Ypixel, colortable[paperColor]
pix[Xpixel + Ypixel*256] = bOR(colortable[paperColor], ASL(0x00ffffff, 24))//colortable[paperColor]+ 0xff000000
ENDSELECT
Xpixel = Xpixel + 1
video = bAND(bajt,2) //;7
SELECT video
CASE 2
//SETPIXEL Xpixel,Ypixel, colortable[inkcolor]
pix[Xpixel + Ypixel*256] = bOR(colortable[inkcolor], ASL(0x00ffffff,24))//colortable[inkcolor]+ 0xff000000
CASE 0
//SETPIXEL Xpixel,Ypixel, colortable[paperColor]
pix[Xpixel + Ypixel*256] = bOR(colortable[paperColor], ASL(0x00ffffff, 24))//colortable[paperColor]+ 0xff000000
ENDSELECT
Xpixel = Xpixel + 1
video = bAND(bajt,1) //;8
SELECT video
CASE 1
//SETPIXEL Xpixel,Ypixel, colortable[inkcolor]
pix[Xpixel + Ypixel*256] = bOR(colortable[inkcolor], ASL(0x00ffffff,24))//colortable[inkcolor]+ 0xff000000
CASE 0
//SETPIXEL Xpixel,Ypixel, colortable[paperColor]
pix[Xpixel + Ypixel*256] = bOR(colortable[paperColor], ASL(0x00ffffff, 24))//colortable[paperColor]+ 0xff000000
ENDSELECT
Xpixel = Xpixel + 1
NEXT
Ypixel = Ypixel + 1
NEXT
NEXT
NEXT
MEM2SPRITE(pix[], 1, 256, 256)
DRAWSPRITE 1, 32, 32
ENDFUNCTION
//FLASH timing
FUNCTION FlashEffect:
IF GETTIMERALL() > oldTime + time
IF flashstate = TRUE
flashstate = FALSE
oldTime=GETTIMERALL()
ELSE
flashstate = TRUE
oldTime=GETTIMERALL()
ENDIF
ENDIF
ENDFUNCTION
//ZXGreyscale
FUNCTION MakeGrey:
FOR k=0 TO 15
colortable[k] = Grey(colortable[k])
NEXT
ENDFUNCTION
//ZXSpectrum colors
FUNCTION MakeColors:
colortable[0] = RGB(0,0,0) //;BLACK
colortable[1] = RGB(0,10,120) //;BLUE
colortable[2] = RGB(200,20,20) //;RED
colortable[3] = RGB(200,40,200) //;MAGENTA
colortable[4] = RGB(20,200,20) //;GREEN
colortable[5] = RGB(40,200,200) //;CYAN
colortable[6] = RGB(200,200,40) //;YELLOW
colortable[7] = RGB(200,200,200) //;WHITE
colortable[8] = RGB(1,1,1) //;BLACK + BRIGHT
colortable[9] = RGB(0,20,200) //;BLUE + BRIGHT
colortable[10] = RGB(255,40,40) //;RED + BRIGHT
colortable[11] = RGB(255,80,255) //;MAGENTA + BRIGHT
colortable[12] = RGB(40,255,40) //;GREEN + BRIGHT
colortable[13] = RGB(80,255,255) //;CYAN + BRIGHT
colortable[14] = RGB(255,255,80) //;YELLOW + BRIGHT
colortable[15] = RGB(255,255,255) //;WHITE + BRIGHT
ENDFUNCTION
FUNCTION Grey: rgb1
red1=bAND(ASR(rgb1,16), 255)
green1=bAND(ASR(rgb1,8),255)
blue1=bAND(rgb1,255)
//simple grayscale
gray=(red1+green1+blue1)/3
//greyscale by Peter Scheutz
//gray=red1*0.3 + green1*.059 + blue1*0.11
red1=gray
green1=gray
blue1=gray
RETURN RGB(red1, green1, blue1)
ENDFUNCTION
// DELTA TIME CLASS by AMON ---------------------------------
TYPE DeltaTimer
targetfps#
currentticks#
lastticks#
frametime#
delta#
FUNCTION InitDelta :
self.targetfps = 0.0
self.currentticks = 0.0
self.lastticks = 0.0
self.frametime = 0.0
self.delta = 0.0
RETURN TRUE
ENDFUNCTION
FUNCTION SetDeltaFPS : fps#
self.targetfps = fps
self.lastticks = GETTIMERALL()
RETURN fps
ENDFUNCTION
FUNCTION UpdateDelta :
self.currentticks = GETTIMERALL()
self.frametime = self.currentticks - self.lastticks
self.delta = self.frametime / (1000.0 / self.targetfps)
self.lastticks = self.currentticks
game_delta = self.delta
// Logic()
RETURN TRUE
ENDFUNCTION
ENDTYPE
(http://www.mikele.kylos.pl/ZXSpec1.jpg)
Regards,
M.
[attachment deleted by admin]
Nice one, reminds me of my old routine 8)