Hi together,
as some of you know, I begun to code the RPG game "Elvira - Mistress of the Dark" for CPC 6128.
[cpc=http://cpcwiki.eu/forum/index.php?action=dlattach;topic=320.0;attach=159,elvira,1]PARADOS[/cpc]
For this project I need help from coders.
(I want to finish it...)
If someone is interested in this, please contact me.
Cheers,
Markus
Please, guys, do lend a hand... this is a great and really, really really ambitious project. I think it's a miracle that Markus has brought it so far, it'd be shame to see it go down the drain!
Come onnnnnnnnnnn............
Please helppppp...
(http://cpc-live.com/elvira/elvira_preview2.gif)
Don't let this project die... :-\
Hello,
Sorry, I have no time at the moment to help you (Color lines... ). I think you should explain at what step you project is (gfx, music, game logic) and what kind of help you need (code all the game or only specific routines, for example :-) ). That may motivate some CPC coders.
T&J/GPA
As a sidenote, who would've thought this can be done in Basic?...
Quote from: Gryzor on 09:06, 15 August 09
As a sidenote, who would've thought this can be done in Basic?...
That's not 100% correct.
BASIC only puts some logic together, uses some variables to make this or that.
The most power is taken from Elvira's RSX commands. (Specially designed for this game)
I will post now, in what case I need your help.It has to do with the huge inventory.
The game uses about
150-
200 items.
They can be picked up, used, combined together etc...
Each item has a sprite (So each item must know it's address)
As you can see in the animated GIF above, i need the inventory box working.
- Select / deselect an item
- Scroll the box up/down if you have more than 12 items
- Drop / pick up items in a room
To let you know:
- The cursor is interrupt driven. It returns x,y coords when press fire / space and it moves on cursor keys/joystick movement/AMX mouse, too
Of course, the game could be re-coded completely, if this makes things easier.
But I appreciate my RSX routines for it, because it's really easy to handle.
(Only thing is: I can only use PCCPC from Ludovic Deplanqué (Demoniak) to compress / cutout the images/sprites)
Some people already asked me, why I don't code this game for 256k/512k
Answer is simple:
- For basic it makes no difference, how many memory you have free, it's limited to 16k (Because himem is set to &3FFF)
- The game should work on a un-touched CPC 6128
- There exist a C64 version which runs on 64k Commodore. (Without nice animations, sounds etc...)
Maybe you should post the source code so others may offer suggestions or better determine whether they are able to contribute??
Quote from: lachlank on 10:30, 15 August 09
Maybe you should post the source code so others may offer suggestions or better determine whether they are able to contribute??
For basic it's not easy, because the game uses lots of small parts.
(Using 'CHAIN MERGE' command)
But here's the ASM code:
; Elvira - Mistress of the Dark
; RSX routines
; ©2007-2009 by Demoniak & Devilmarkus
;
; AYC-music-playback done 2009 by Devilmarkus
;
;
; Addresses & locations for built-in sprites:
;
; 1, 54,&9EC0 UP-Arrow
; 7, 62,&9EF0 DOWN-Arrow
; 4, 88,&9F1D FORWARD-Arrow
; 2,109,&9F49 TURN_AROUND-Arrow
; 1,101,&9F91 TURN_LEFT-Arrow
; 6,101,&9FB9 TURN_RIGHT-Arrow
;
nolist
org &9800
;Mainpart
BuffSpt equ #7C00
BuffScr equ #4000
call IntOn
LD HL,BufferRsx
LD BC,PtrRsx
JP #BCD1
PtrRsx:
DW RSX_TABLE
JP DepkSpt
JP DepkShp
JP DepkWin
JP DepkScr
JP CursorOn
JP SetPosCursor
JP GetPosCursor
JP CursorOff
JP Bank
JP CLS
JP MusicOn
JP StopMusic
JP PauseMusic
JP Mode
JP Box
JP Arrow
nop
nop
nop
RSX_TABLE:
DB "DEPKSP","T"+#80
DB "DEPKSH","P"+#80
DB "DEPKWI","N"+#80
DB "DEPKSC","R"+#80
DB "CURSORO","N"+#80
DB "SETCURSO","R"+#80
DB "GETCURSO","R"+#80
DB "CURSOROF","F"+#80
DB "BAN","K"+#80
DB "CL","S"+#80
DB "PLA","Y"+#80
DB "STO","P"+#80
DB "PAUS","E"+#80
DB "MOD","E"+#80
DB "BO","X"+#80
DB "ARRO","W"+#80
nop
nop
nop
nop
;
; Depack sprite
;
DepkSpt:
LD H,(IX+1)
LD L,(IX+0)
LD DE,XD
LDI ; store XD
LDI ; store YD
LDI ; stora XA
LDI ; store YA
LD B,(IX+2) ; New XD coordinate
LD C,(IX+4) ; New YD coordinate
LD IX,XD
LD A,(IX+2) ; XA
SUB (IX+0) ; XA - XD
ADD A,C ; XA - XD + NewXD
LD (IX+2),A
LD A,(IX+3) ; YA
SUB (IX+1) ; YA - YD
ADD A,B ; YA - YD + NewYD
LD (IX+3),A
LD (IX+0),C ; New XD
LD (IX+1),B ; New YD
LD DE,BuffSpt ; Temporary buffer
CALL DepkLzw ; depack
CALL CalcCoord
LD DE,BuffSpt
NbColSpt:
DB #DD : LD H,0
DrawSpt1:
PUSH HL
NbLigSpt:
DB #DD : LD L,0
DrawSpt2:
LD A,(DE) ; Byte sprite
LD C,A
LD B,A
RRCA
RRCA
RRCA
RRCA
OR C ; Bits 0-3 | Bits 4-7 in all bits
CPL
LD C,A
LD A,(HL) ; Byte screen memory
AND C
OR B ; Byte sprite
LD (HL),A
INC DE
LD A,H
ADD A,8
LD H,A
JR NC,DrawSpt3
LD BC,#C050
ADD HL,BC
DrawSpt3:
DB #DD : DEC L
JR NZ,DrawSpt2
POP HL
INC HL
DB #DD : DEC H
JR NZ,DrawSpt1
RET
;
; Depack sprite XOR
;
DepkShp:
LD H,(IX+1)
LD L,(IX+0)
LD DE,XD
LDI ; store XD
LDI ; store YD
LDI ; stora XA
LDI ; store YA
LD B,(IX+2) ; New XD coordinate
LD C,(IX+4) ; New YD coordinate
LD IX,XD
LD A,(IX+2) ; XA
SUB (IX+0) ; XA - XD
ADD A,C ; XA - XD + NewXD
LD (IX+2),A
LD A,(IX+3) ; YA
SUB (IX+1) ; YA - YD
ADD A,B ; YA - YD + NewYD
LD (IX+3),A
LD (IX+0),C ; New XD
LD (IX+1),B ; New YD
LD DE,BuffSpt ; Temporary buffer
CALL DepkLzw ; depack
CALL CalcCoordx
LD DE,BuffSpt
NbColShp:
DB #DD : LD H,0
DrawSpt1x:
PUSH HL
NbLigShp:
DB #DD : LD L,0
DrawSpt2x:
LD A,(DE) ; Byte sprite
LD C,A
LD B,A
RRCA
RRCA
RRCA
RRCA
OR C ; Bits 0-3 | Bits 4-7 in all bits
CPL
LD C,A
LD A,(HL) ; Byte screen memory
; AND C
; OR B ; Byte sprite
XOR B
LD (HL),A
INC DE
LD A,H
ADD A,8
LD H,A
JR NC,DrawSpt3x
LD BC,#C050
ADD HL,BC
DrawSpt3x:
DB #DD : DEC L
JR NZ,DrawSpt2x
POP HL
INC HL
DB #DD : DEC H
JR NZ,DrawSpt1x
RET
CalcCoord:
LD H,#C0 ; Start video offset
LD A,(XD)
LD L,A
LD A,(YD)
AND A ; No y offset ?
JR Z,CalcDebBcl
LD B,A
LD C,8
LD DE,#C050
CalcS1:
LD A,H
ADD A,C
LD H,A
JR NC,CalcS2
ADD HL,DE
CalcS2:
DJNZ CalcS1
;
; Calculate size in Y
;
CalcDebBcl:
LD A,(YD)
LD B,A
LD A,(YA)
SUB B
INC A
LD B,A ; B = numbers of y
;
; Calculate numbers of X
;
LD A,(XD)
LD C,A
LD A,(XA)
SUB C
INC A
LD (NbColSpt+2),A ; numbers of x
LD A,B
LD (NbLigSpt+2),A
RET
; XOR
CalcCoordx:
LD H,#C0 ; Start video offset
LD A,(XD)
LD L,A
LD A,(YD)
AND A ; No y offset ?
JR Z,CalcDebBclx
LD B,A
LD C,8
LD DE,#C050
CalcS1x:
LD A,H
ADD A,C
LD H,A
JR NC,CalcS2x
ADD HL,DE
CalcS2x:
DJNZ CalcS1x
;
; Calculate size in Y
;
CalcDebBclx:
LD A,(YD)
LD B,A
LD A,(YA)
SUB B
INC A
LD B,A ; B = numbers of y
;
; Calculate numbers of X
;
LD A,(XD)
LD C,A
LD A,(XA)
SUB C
INC A
LD (NbColShp+2),A ; numbers of x
LD A,B
LD (NbLigShp+2),A
RET
;
; Depack Window
;
DepkWin:
LD H,(IX+1)
LD L,(IX+0)
INC HL
INC HL
INC HL
INC HL
LD DE,BuffSpt
CALL DepkLzw
LD HL,BuffSpt
LD DE,#D80C
DB #DD : LD H,127
DepkWin1:
LD A,56
LD BC,127
DepkWin2:
LDI
ADD HL,BC
INC C
DEC A
JR NZ,DepkWin2
LD BC,#E439
ADD HL,BC
EX DE,HL
LD BC,#7C8 ; #800 - 56
ADD HL,BC
JR NC,DepkWin3
LD BC,#C050
ADD HL,BC
DepkWin3:
EX DE,HL
DB #DD : DEC H
JR NZ,DepkWin1
RET
;
; Depack Screen
;
DepkScr:
LD H,(IX+1)
LD L,(IX+0)
LD DE,BuffScr
CALL DepkLzw
LD HL,BuffScr
LD DE,#C000
DB #DD : LD H,200
DepkScr1:
LD A,80 ; 80 columns
LD BC,200
DepkScr2:
LDI
ADD HL,BC
INC C
DEC A
JR NZ,DepkScr2
LD BC,#C181
ADD HL,BC
EX DE,HL
LD BC,#7B0 ; #800 - 80
ADD HL,BC
JR NC,DepkScr3
LD BC,#C050
ADD HL,BC
DepkScr3:
EX DE,HL
DB #DD : DEC H
JR NZ,DepkScr1
RET
Bank:
LD A,(IX+0)
LD (&97ff),A
AND 7
OR #C0
LD B,#7F
OUT (C),A
RET
; Music Control
;
MusicOn:
LD A,&CD
LD (MusicData),A
LD HL,PlayMusic
LD (MusicData+1),HL
LD A,&C9
LD (MusicData+3),A
RET
StopMusic:
LD BC,&7F00
LD C,&C7
OUT (C),C
CALL &4000
LD A,(&97FF)
LD BC,&7F00
OUT (C),A
PauseMusic:
LD A,&C9
LD (MusicData),A
RET
PlayMusic:
DI
PUSH AF
PUSH BC
PUSH DE
PUSH HL
PUSH IX
PUSH IY
EX AF,AF'
PUSH AF
EX AF,AF'
LD BC,&7F00
LD C,&C7
OUT (C),C
CALL &4003
LD A,(&97FF)
LD BC,&7F00
OUT (C),A
EX AF,AF'
POP AF
EX AF,AF'
POP IY
POP IX
POP HL
POP DE
POP BC
POP AF
EI
RET
; Cursor On
;
CursorOn:
LD A,&CD
LD (CursorData),A
LD HL,StartCursor
LD (CursorData+ 1),HL
LD A,&C9
LD (CursorData+ 3),A
RET
CursorOff:
CALL RestoreScr
LD A,&C9
LD (CursorData),A
LD HL,#FFFF
LD (X1),HL ; Forcing cursor display
LD HL,0
LD (RestoreScr+1),HL ; No former memory
RET
IntOn:
LD A,0
AND A ; Driver already installed?
RET NZ ; If yes, does nothing
INC A
LD (IntOn+1),A ; Indicates driver
LD HL,BlocEvent
LD DE,InterruptLoop
LD BC,#8100
JP #BCD7
InterruptLoop:
call cursordata
call musicdata
ret
;
; Set cursor position
;
SetPosCursor:
LD E,(IX+0)
LD D,(IX+1)
LD L,(IX+2)
LD H,(IX+3)
LD (X),HL
EX DE,HL
LD (Y),HL
RET
;
; Get cursor position
;
GetPosCursor:
LD H,(IX+1)
LD L,(IX+0)
LD B,0
LD A,(Y)
LD (HL),A
INC HL
LD (HL),B
LD H,(IX+3)
LD L,(IX+2)
LD A,(X)
LD (HL),A
INC HL
LD (HL),B
RET
StartCursor:
DI
PUSH AF
PUSH BC
PUSH DE
PUSH HL
PUSH IX
EXX
LD A,C
SET 3,A ; cut upper ROM
OUT (C),A
EXX
LD HL,Y1
LD A,(Y)
CP (HL)
JR NZ,FctAff
LD HL,X1
LD A,(X)
CP (HL)
JR Z,DeplCurseur
;
; Move -> Display new cursor
;
FctAff:
CALL RestoreScr
LD A,(X)
LD (X1),A
LD E,A ; E = x
LD A,(Y)
LD (Y1),A
LD D,A ; D = y
; Adresse = #C000 + (Y/8)*80 + (Y-(Y/8)*8)*#800 + X/4
SRL E ; E = x/4
AND #F8
LD L,A ; HL = (y/8)*8
LD H,0
LD A,D
LD D,H ; D = 0
SUB L ; A = (y-(y/8)*8)
ADD HL,HL ; HL * 2
LD B,H
LD C,L ; BC = HL * 2
ADD HL,HL ; HL * 4
ADD HL,HL ; HL * 8
ADD HL,BC ; HL * 10 (y/8)*80
ADD HL,DE ; HL = HL + x/4
RLA
RLA
RLA ; A = 8*(y-(y/8)*8)
OR #C0
ADD A,H
LD H,A
LD (RestoreScr+1),HL
CALL SavScrCurseur
LD A,(X)
RRCA
RRCA
AND #40 ; Keep 1 bit (shifted right 2x = 40 #)
LD C,A
LD B,0
LD HL,SptCurseur1 ; Datas sprites arrow
ADD HL,BC ; Cursor 1 or 2
EX DE,HL
LD HL,(RestoreScr+1) ; HL = address screen display
CALL AfficheCurseur ; View
DeplCurseur:
XOR A ; Code UP Cursorkey
CALL #BB1E
CALL NZ,MvtHaut
LD A,#48 ; Code UP Joystick
CALL #BB1E
CALL NZ,MvtHaut
LD A,#02 ; Code DOWN Cursorkey
CALL #BB1E
CALL NZ,MvtBas
LD A,#49 ; Code DOWN Joystick
CALL #BB1E
CALL NZ,MvtBas
LD A,#01 ; Code RIGHT Cursorkey
CALL #BB1E
CALL NZ,MvtDroite
LD A,#4B ; Code RIGHT Joystick
CALL #BB1E
CALL NZ,MvtDroite
LD A,#08 ; Code LEFT Cursorkey
CALL #BB1E
CALL NZ,MvtGauche
LD A,#4A ; Code LEFT Joystick
CALL #BB1E
CALL NZ,MvtGauche
POP IX
POP HL
POP DE
POP BC
POP AF
EI
RET
MvtBas:
LD A,(Y)
CP 186
RET NC
ADD A,2
LD (Y),A
RET
MvtHaut:
LD A,(Y)
CP 2
RET C
SUB 2
LD (Y),A
RET
MvtGauche:
LD A,(X)
AND A
RET Z
DEC A
LD (X),A
RET
MvtDroite:
LD A,(X)
CP 153
RET NC
INC A
LD (X),A
RET
SavScrCurseur:
LD DE,BuffFleche
LD A,14
SavScrCurseur2:
LDI
LDI
LDI
LDI
LD BC,#7FC
ADD HL,BC
JR NC,SavScrCurseur3
LD BC,#C050
ADD HL,BC
SavScrCurseur3:
DEC A
JR NZ,SavScrCurseur2
RET
RestoreScr:
LD HL,0
LD A,H
OR L
RET Z
LD DE,BuffFleche
LD A,14
RestoreScr2:
EX DE,HL
LDI
LDI
LDI
LDI
EX DE,HL
LD BC,#7FC
ADD HL,BC
JR NC,RestoreScr3
LD BC,#C050
ADD HL,BC
RestoreScr3:
DEC A
JR NZ,RestoreScr2
RET
AfficheCurseur:
DB #DD : LD H,14
AfficheCurseur2:
LD B,4
EX DE,HL
AfficheCurseur3:
LD A,(HL) ; Reading data sprites
LD C,#55
AND C
JR Z,AfficheCurseur4
LD C,0
AfficheCurseur4:
LD A,(HL)
AND #AA
JR NZ,AfficheCurseur5
LD A,C
OR #AA
LD C,A
AfficheCurseur5:
LD A,(DE) ; Reading mem. screen
AND C
OR (HL)
LD (DE),A
INC HL
INC DE
DJNZ AfficheCurseur3
EX DE,HL
LD BC,#7FC
ADD HL,BC
JR NC,AfficheCurseur6
LD BC,#C050
ADD HL,BC
AfficheCurseur6:
DB #DD : DEC H
JR NZ,AfficheCurseur2
RET
DepkLzw:
XOR A
LD (BclLzw+1),A
;
TstBitLzw:
LD A,(HL)
INC HL
RRA ; Turnover calculation flag C
SET 7,A ; Set bit 7 keeping flag C
LD (BclLzw+1),A
JR C,TstCodeLzw
CopByteLzw:
LDI
;
BclLzw:
LD A,0
RR A ; Flags rotation calculation with C and Z
LD (BclLzw+1),A
JR Z,TstBitLzw
JR NC,CopByteLzw
TstCodeLzw:
;
; a = inbuffer[ inbytes ];
;
LD A,(HL)
AND A
;
; More bytes to process
; = end
;
RET Z
INC HL
LD B,A ; B = inbuffer[ inbytes ]
RLCA
JR NC,TstLzw40
;
; length = 3 + ( ( inbuffer[ inbytes ] >> 4 ) & 7 );
; index = ( inbuffer[ inbytes++ ] & 15 ) << 8;
; index |= inbuffer[ inbytes++ ];
; index++;
;
LD C,(HL) ; C = low index
RLCA
RLCA
RLCA
AND 7
ADD A,3
PUSH HL
LD H,A ; H = length
LD A,B ; B = inbuffer[inbytes]
AND #0F
LD B,A ; B = poids fort index
LD A,H ; A = Length
LD H,D
LD L,E
SCF ; Re-position flag C
SBC HL,BC ; HL=HL-(BC-1)
LD B,0
LD C,A
LDIR
POP HL
INC HL
JR BclLzw
;
TstLzw40:
RLCA
JR NC,TstLzw20
;
; length = 2;
; index = inbuffer[ inbytes++ ] & 0x3f;
; index++;
;
LD C,B
RES 6,C
LD B,0 ; BC = index -1, without +1 car flag C = 1
PUSH HL
LD H,D
LD L,E
SBC HL,BC
LDI
LDI
POP HL
JR BclLzw
;
TstLzw20:
RLCA
JR NC,TstLzw10
;
; length = 2 + ( inbuffer[ inbytes++ ] & 31 );
; index = inbuffer[ inbytes++ ];
; index++;
;
PUSH HL
LD A,B
RES 5,A
LD C,(HL) ; C = index
LD B,0
LD H,D
LD L,E
SBC HL,BC
ADD A,2
LD C,A ; C = length
LDIR
POP HL
INC HL
JR BclLzw
;
TstLzw10:
RLCA
JR NC,CodeLzw0F
;
; index = ( inbuffer[ inbytes++ ] & 15 ) << 8;
; index |= inbuffer[ inbytes++ ];
; length = inbuffer[ inbytes++ ] + 1;
; index++;
;
RES 4,B ; B = index(high)
LD C,(HL) ; C = index(low)
INC HL
LD A,(HL) ; A = length - 1
PUSH HL
LD H,D
LD L,E
SBC HL,BC ; Flag C=1 -> hl=hl-(bc+1)
LD B,0
LD C,A
INC BC ; BC = length
LDIR
POP HL
INC HL
JR BclLzw
;
CodeLzw0F:
LD C,(HL)
PUSH HL
LD H,D
LD L,E
LD A,B
CP #0F
JR NZ,CodeLzw02
;
; length = index = inbuffer[ inbytes + 1 ] + 1;
; inbytes += 2;
;
XOR A
LD B,A
INC BC
SBC HL,BC
LDIR
POP HL
INC HL
JP BclLzw
;
CodeLzw02:
CP 2
JR C,CodeLzw01
;
; length = index = inbuffer[ inbytes ];
;
LD C,A
XOR A
LD B,A
SBC HL,BC
LDIR
POP HL
JP BclLzw
;
; length = index = 256;
;
CodeLzw01: ; here, A = B = 1
XOR A
LD C,A
DEC H
LDIR
POP HL
JP BclLzw
SptCurseur1:
DB #C0, #C0, #00, #00, #90, #60, #00, #00
DB #90, #65, #00, #00, #C0, #20, #00, #00
DB #C0, #80, #00, #00, #C0, #90, #00, #00
DB #C5, #C0, #00, #00, #80, #CA, #20, #00
DB #8A, #40, #80, #00, #00, #45, #90, #00
DB #00, #00, #C0, #80, #00, #00, #CA, #8A
DB #00, #00, #40, #00, #00, #00, #45, #00
;
; Here for 8 bytes alignment on 64 bytes
;
X:
DB 40
Y:
DB 100
X1:
DB 0
Y1:
DB 0
XD:
DB 0
YD:
DB 0
XA:
DB 0
YA:
DB 0
;
; Cursor shift one pixel to the right
;
DB #40, #C0, #80, #00, #40, #30, #80, #00
DB #40, #30, #8A, #00, #40, #90, #00, #00
DB #40, #C0, #00, #00, #40, #C0, #20, #00
DB #40, #CA, #80, #00, #40, #45, #90, #00
DB #45, #00, #C0, #00, #00, #00, #CA, #20
DB #00, #00, #40, #C0, #00, #00, #45, #C5
DB #00, #00, #00, #80, #00, #00, #00, #8A
BuffFleche:
DS 56
CLS:
LD HL,&C5B0 ;HL is 'adr' variable
LD C,51 ;Rows
clear_area:
PUSH HL
LD B,&30
LD A,&0
clear_line:
LD (HL),A
INC HL
DJNZ clear_line
POP HL
CALL &BC26 ;SCR_NEXT_LINE
DEC C
JR NZ,clear_area
RET
Box:
LD hl,BoxSprite
LD (ix+0),l
LD (ix+1),h
JP DepkShp
RET
Mode:
LD A,1
CALL &BC0E
CALL &BD1C
RET
Arrow:
LD hl,ArrowSprite
LD (ix+0),l
LD (ix+1),h
JP DepkShp
RET
; Double Arrow & Box data
ArrowSprite:
DB &48,&08,&4C,&2E,&0C,&00,&00,&02,&02,&44,&44,&CD,&D8,&E7,&24,&09
DB &06,&07,&D8,&CD,&58,&26,&0B,&21,&22,&80,&C8,&9A,&90,&CF,&E5,&3C
DB &CD,&02,&15,&02,&CC,&23,&13,&CC,&23,&0B,&3C,&E5,&CF,&08,&90,&9A
DB &C8,&23,&2A,&88,&88,&DA,&D5,&80,&65,&E0,&30,&30,&C0,&C0,&3F,&02
DB &55,&21,&03,&FF,&23,&26,&FF,&25,&0D,&C0,&58,&E0,&98,&65,&D5,&DA
DB &64,&22,&14,&A0,&AA,&6A,&B0,&CF,&FF,&0A,&AA,&02,&02,&AA,&23,&26
DB &22,&AA,&23,&0B,&0A,&FF,&CF,&62,&AA,&A0,&39,&2A,&86,&A0,&AA,&31
DB &9B,&28,&22
BoxSprite:
DB &00,&A0,&06,&B9,&E0,&B0,&20,&65,&8A,&CF,&02,&04,&08,&CB,&04,&55
DB &B0,&45,&00,&00,&02,&04,&73,&08,&06,&45,&CF,&0F,&19,&0F,&33,&0F
DB &19,&70,&E8,&9A,&10,&CF,&45,&45,&04,&08,&04,&05,&55,&70,&00,&00
MusicData:
ret:nop:nop:nop
Cursordata:
ret:nop:nop:nop
BlocEvent:
DS 16
ArrowData:
DB &01,&36,&04,&47,&CC,&00,&00,&02,&02,&45,&45,&24,&07,&26,&0D,&F0
DB &CA,&CA,&C0,&CF,&45,&02,&04,&02,&80,&8A,&8A,&C5,&C5,&60,&60,&C0
DB &44,&63,&02,&04,&C5,&CF,&CF,&22,&25,&21,&15,&CF,&03,&2A,&35,&00
DB &07,&3E,&0A,&50,&9C,&00,&00,&02,&04,&03,&45,&45,&08,&87,&02,&04
DB &03,&CF,&C0,&CA,&CA,&22,&16,&70,&CF,&CF,&C5,&C5,&02,&04,&02,&C0
DB &A4,&60,&60,&44,&8A,&8A,&29,&38,&CF,&2C,&0E,&01,&00,&04,&58,&07
DB &68,&84,&00,&00,&02,&45,&45,&CA,&CF,&22,&07,&C2,&00,&25,&0C,&CA
DB &90,&90,&C0,&44,&02,&07,&04,&4E,&52,&8A,&8A,&C5,&C5,&C0,&FE,&CF
DB &45,&02,&03,&26,&27,&0A,&27,&3A,&00,&02,&6D,&07,&7F,&9C,&00,&00
DB &02,&04,&03,&45,&45,&29,&0C,&C1,&23,&0F,&45,&CF,&C0,&CA,&CA,&23
DB &16,&49,&03,&48,&02,&CF,&CF,&C5,&C5,&C5,&C0,&64,&60,&60,&44,&8A
DB &8A,&4B,&48,&C5,&EC,&CF,&8A,&22,&28,&55,&8A,&23,&07,&53,&5C,&FF
DB &21,&23,&21,&37,&03,&06,&21,&14,&5B,&03,&22,&38,&0F,&03,&02,&5E
DB &00,&01,&65,&05,&6E,&C0,&00,&00,&45,&45,&CA,&CA,&43,&47,&C0,&8A
DB &8A,&C5,&C5,&60,&60,&43,&47,&E1,&4B,&CF,&CF,&C0,&C0,&43,&47,&0A
DB &1D,&22,&0B,&8A,&22,&1A,&24,&0A,&00,&06,&65,&0A,&6E,&00,&00,&00
DB &45,&45,&CA,&CA,&CF,&45,&C3,&47,&02,&CF,&CF,&C0,&C0,&43,&0A,&81
DB &47,&8A,&8A,&C5,&C5,&60,&60,&43,&0F,&47,&22,&15,&06
BufferRsx:
DS 4
Hello,
What is your problem with the inventory ? How to code in memory informations about the object ? How to manage the sprite objects in the inventory window ? That's not quite clear :-).
T&J/GPA
Quote from: TomEtJerry on 14:22, 15 August 09
Hello,
What is your problem with the inventory ? How to code in memory informations about the object ? How to manage the sprite objects in the inventory window ? That's not quite clear :-).
T&J/GPA
All of them ::)
As you can see, no further feedback is here.
Project cancelled.
Quote from: Devilmarkus on 15:50, 16 October 09
As you can see, no further feedback is here.
Project cancelled.
Hmmm.. maybe you should reconsider..
Because its a nice project..
But it is very unclear what exactly you need help for?????
Maybe you could be more specific?
/CPCLER
I need help for creating the inventory and it's routine (handling, pick up/drop things, use objects etc...)
I only have sprites for them. But they must work like an inventory. (Interactivity)
I also think, BASIC ram is too low to create it.
Quote from: Devilmarkus on 16:18, 16 October 09
I need help for creating the inventory and it's routine (handling, pick up/drop things, use objects etc...)
I only have sprites for them. But they must work like an inventory. (Interactivity)
I also think, BASIC ram is too low to create it.
So it's not actually a BASIC job - am i right? More like an RSX solution?
Is the sprites for the inventory items stored in the 2nd 64kb of the 6128. How many items do you want the inventory to hold?
/CPCLER
Quote from: CPCLER on 21:11, 16 October 09
So it's not actually a BASIC job - am i right? More like an RSX solution?
Is the sprites for the inventory items stored in the 2nd 64kb of the 6128. How many items do you want the inventory to hold?
/CPCLER
The RSX is already written.
Sprites are compacted and in different banks.
Normal:
Screens - C0, C1
Sprites: C6
Music + player: C7
Animations:
C0-C6
This can be different. I first must think about a new code for the game engine (BASIC) but this I can do forst, when I've got a solution for the inventory routine.
Ca. 150 items.
Sprites + calling them to screen = RSX
logic for inventory should be in BASIC. The logic must know:
- Sprite's address
- Item's properties (weight, size, eatable/not, carryable/not etc....)
Maybe I will re-code the most parts in BASIC so that I can use more free ram for it.
Sure is:
Each "Room" will have it's own BASIC-file. (Using CHAIN MERGE...) and each Room will have different entry points, depends on from which area you entered.
The inventory items must be useable in all rooms. Where 1 room has info for items, which are @ beginning in this room, and which the user can pick up.
Dropped items must be stored in the room, where you dropped them (logical)
Easiest way will be to use room numbers. (Each room has a number, 0-50 for example)
So we could do with inventory, too:
0 - in hand
1 - in room 1
2... etc..
51 - disappeared/unavailable
Or similar.
Also, it must be possible to combine items, use axe on wood etc...
Hard way.
The rooms itself need only info about:
- is there a monster in?
- In which directions the player can turn? (north, east, south, west, up/down)
- address for GFX for the sides (1 room has 1 GFX file, with different scenes in, normally 4 GFX for 1 room)
and some more... Like mouse-click-areas etc... But this will be easy to implement.
I am still not sure what you want:
Okay so if there are 150 distinct items... Each item can have 3 states:
Placed in a room.
In the players inventory.
Visible/Invisible.
This means the the object to room mapping and inventory will take up 1200 bytes.
Each record will look like this and could be placed in a bank:
; Datastructure for inventory
;
; eg.
; ITEM#1
; DB defaultRoomNo,RoomNo,taken,visible:DW spriteAdr
; ITEM#2
; DB defaultRoomNo,RoomNo,taken,visible:DW spriteAdr
;
; ..
;
; ITEM#150
; .. Structure size for inventory 150 items (8*150) = 1200 bytes
defaultRoomNo - Where an item first occurs (needed for initialisation purposes)
RoomNo - Which room number the items is currently located (When not in the players inventory)
taken - True/False (in the players inventory or not!)
visible - True/False(Visible to the player or not!)
spriteAdr - Address of sprite date (Needed for displaying icon for item)
RSX Commands could be made to accomodate the usage of the inventory (But again this is not a BASIC job)
|noitems,@i% ; Number of items in inventory
|showinventory,from% ; Display inventory from inventory item.
|getitem,x%,y%,@i% ; Get item no from displayed at screen coords x,y
well something like that!
/CPCLER
PS. Are you avare that there are differences in the calling conventions to RSX commands between the 464 / 6128...
Quote from: Devilmarkus on 21:37, 16 October 09
The RSX is already written.
Sprites are compacted and in different banks.
Normal:
Screens - C0, C1
Sprites: C6
Music + player: C7
Animations:
C0-C6
This can be different. I first must think about a new code for the game engine (BASIC) but this I can do forst, when I've got a solution for the inventory routine.
Ca. 150 items.
Sprites + calling them to screen = RSX
logic for inventory should be in BASIC. The logic must know:
- Sprite's address
- Item's properties (weight, size, eatable/not, carryable/not etc....)
Maybe I will re-code the most parts in BASIC so that I can use more free ram for it.
Sure is:
Each "Room" will have it's own BASIC-file. (Using CHAIN MERGE...) and each Room will have different entry points, depends on from which area you entered.
The inventory items must be useable in all rooms. Where 1 room has info for items, which are @ beginning in this room, and which the user can pick up.
Dropped items must be stored in the room, where you dropped them (logical)
Easiest way will be to use room numbers. (Each room has a number, 0-50 for example)
So we could do with inventory, too:
0 - in hand
1 - in room 1
2... etc..
51 - disappeared/unavailable
Or similar.
Also, it must be possible to combine items, use axe on wood etc...
Hard way.
The rooms itself need only info about:
- is there a monster in?
- In which directions the player can turn? (north, east, south, west, up/down)
- address for GFX for the sides (1 room has 1 GFX file, with different scenes in, normally 4 GFX for 1 room)
and some more... Like mouse-click-areas etc... But this will be easy to implement.
Hi Markus
Ah.. I see the preview.. The game seems to be in a pretty advanced stage, a pity to abandon it now!
BTW. I think the attached .dsk is currupt. Also why is the the files hidden and the basic program protected.
It's pretty anoying when one want to see how much space the different part take and how things are done!
/CPCLER
Quote from: Devilmarkus on 20:59, 31 July 09
Hi together,
as some of you know, I begun to code the RPG game "Elvira - Mistress of the Dark" for CPC 6128.
[cpc=http://cpcwiki.eu/forum/index.php?action=dlattach;topic=320.0;attach=159,elvira,1]PARADOS[/cpc]
For this project I need help from coders.
(I want to finish it...)
If someone is interested in this, please contact me.
Cheers,
Markus
Quote from: CPCLER on 11:57, 17 October 09
Hi Markus
Ah.. I see the preview.. The game seems to be in a pretty advanced stage, a pity to abandon it now!
BTW. I think the attached .dsk is currupt. Also why is the the files hidden and the basic program protected.
It's pretty anoying when one want to see how much space the different part take and how things are done!
/CPCLER
The DSK is not corrupt. It's Parados formatted (420k)
Some files are hidden, yes.
Also some have protection attribute.
This is not my developer dsk.
The developer dsk was destroyed by emulator. (No, I dont write the emulators name here, but it was not mine ;) )
Suggestion:
Let me first create a few new dsk, with a more memory friendly BASIC part.
I think it'd be a shame for the project to be cancelled... it's so ambitious and beautiful!
Hi, I cast "raise dead" on this topic.
I am at the moment trying to figure how to do a RPG too.
Not easy.
I even believe a proper RPG may be the hardest game to do in fact.
Most were more 16 bit than 8 bit (Might and magic 3 as a prime exemple in my mind)
And if well done graphically, and with a shitton of stuff and items.
This really is a nightmare if you aim at a "dungeons and dragon" or "Warhammer" party management/fight ruleset (it's conbining strategic games, wargames and roleplay/adventure)
So I have few questions concerning your Elvira project.
I remember seeing it on an Amiga.
Look like an adventure game more than a RPG ?
What was the aim of your Games format ?
4-64 or 6-64 or 6-128 ?
Oh yeah, 6128 (I re-read the posts)
Concerning Items in Elvira.
How is it supposed to work ?
Is it an open system with item classes like : weapons, armour, key, gold, quest item ?
each with statistic depending of their class (weapons may have different characteristics or bonus/malus on combats...
while keys or quest item may have only 1 fonction in the game and then vanish when properly used.
Or is it more something like Monkey Isqland : items are all part as a point and click, you just collect them to use them at certain moments/event or combinate them properly to go further through enigms.
Ok, it's a typical Monkey island like item management.
Concerning the "150-200" items.
Well are they all stored in memory always, then just put them in diverses "active state" or "inactive state" depending if you collected them or used them ? (fixed item list)
Or do the game load them when needed ? (variable item list)
Disk enable more frequent loading, so less need to store "unusefull at the moment" datas.
And having 128Ko RAM (2x64) enable a lot more ease to storage datas while still being usable on a large part of Amstrad 8 bit standard machines.
Yet such a game seems quite heavy even for the engine only.
Yes C64 managed a lot, I often wonder how.
The graphics formats may have been simpler than on CPC (hard sprites are 3-1 colours only, lots or implemented hardware functions so less need to developp a big software for effects and so on.
on CPC (and even on Plus) all is softwared and graphics are heavy bitches.
Yes we have almost 4mHz yet while a simple hardware setting enable to move a cursor/pointer thx to a hardsprite, on cpc you have to create a whole subprogramm.
in this I believe a smooth mouse like pointer is not a proper solution for any CPC game (unless you enable a real mouse) :
--it's slow and painfull to use.
--it's probably heavy for the system as it requires an animated masked sprite, and some kind of colision detector to understand it is pointing on a button/option/menu selection/item
a full Keyboard shortcuts system may be better IMO, or some sort of menu browse/selection without a free pointer, yet if you need to "point and click" at pixels in the image (Monkey island like game...) well...maybe limiting it only to the "environment representation" windows ?
Yet a nice way to deal with Amstrad's specifities is to re-think the gameplay a bit.
This is not incompatible with a properly 16bit-ported game.
Yet aiming a 16bit-perfect port may be some kind of unrealistic goal.
Despite heavier Graphical data format, the 16 bit computers were also heavily Ram supllied.
512Ko Ram+720Ko discs was the common setting.
To enable 16bit "perfect" ports, and amstrad should need in fact 256ko Ram and Disk.
Why 256Ko ?
8 bit is half 16 bit, 256Ko is half 512Ko.
But we all know amstrad was cheap on Ram.lol.
so the best we can do is to use 6128 format to get properly realised pseudo 16bit RPG/Adventure/point and click games.
And remember CPC don't really have mouse as a standard option.
So simply getting rid of it can simplify a lot and then lighten the program/engine.
I love to think that Heroquest would have been better if not using a pseudo smooth mouse like pointer.
only getting a highlight selected option/button and using Joy/keys to select/browse them.
(on another note, heroquest would have been greater also if it were recoloured in a Head over heels fashion instead of this shitty monoblue+useless grey)
Also concerning the actions menu.
lots of option there.
a simpler actions list may be workable.
9 different options seems a max to me, as it then allow the use of the Fonctions key on CPC (F1 to F9).
"F0" & " . " & arrows keys may then be used for options such as moovement managements.
And Item selection, well, 2 key to browse the different 12 items "pages", and perhapes also 4 keys+space bar to enable the selection.
Concerning actions menu, it can be greatly simplfied.
open/close is the same action indeed, as something closed would be optend and something opened would be closed.
Lock and unlock too.
one action can be needed to simply switch the state of said object.
lookin and exam seems also to be the same stuff.
other simplification concerning the pointer :
instead of a smooth pixel per pixel, just use a case by case one.
Yes there is no more the possibility to put the famous "only one pixel zone" to pass this enigm, yet this shit was so anoying in point&clicks...
If the item combinaisons is well done, this is quite enough for the game to be fun and interesting.
Also the game seems to need a "text bar".
I mean when you select an item, its name needs to appear written somewhere as the mode0 is somewhat...limited you know... to simply know what and item is by just seeing it.
another aspect is : what is the maximum number of item the player may have in the game ?
Some items are there only to be stored a little time to be used at a specific moment and then "disappear" (sort of).
Or some are to be mixed so they also disappear as such while onother take place (2 objects turned into one only...)
or other may be then dispatched into more Item (broken stuff ?).
others are to be used all along the game (perhaps weapons ?) yet I don't think you end the game with 200 items in your stack.
As a result, there is probably no need to put all items in Ram (despite being compressed data) every time.
The disk can act as some kind of harddisc drive and a limited data transfer/writing can occur more often perhaps.
Why puting Graphic data of an item that you will get at the end of the game in the Ram when you are starting the game ?
So anayse the possible maximum actual amount of stacked items and set it as the potential Ram/datas actually needed.
Then go search more into the disc when needed only.
As a result, knowing how you manage the Game engine-Disk management is important to know.
Many questions in 1 thread :D
To make the game better understandable how it works,
please download it and play.
I made 4 different versions runnable on Windows.
English,
German,
French,
Spanish.
To give you the download URL please write me a PM.
Some infos about game (engine):
- I merge parts of basic code together, each room should have it's own basic file.
(CHAIN MERGE"blah",2000)
- 128k are required!
- Engine needs completely to be rewritten (simple)
- I use RSX commands to put screens, sprites, cursor, play music etc...
(Music and cursor are interrupt driven! Cursor returns X/Y coordinates when press fire/space, Music plays from ram bank &C7)
- I want the CPC version as close as possible to the original game
(But I will not use all spells and items like the original, because you dont need them all to solve the game)
http://www.youtube.com/watch?v=d9ukGxatBxw
;D
I also found a complete youtube video of the entire game.
interesting, and I downloaded the outlet, the solution and so on, i'll give it a look, but as I suck at coding, I won't be of any help on this matter.
I could see it was indeed a proper RPG and not a point and click only game.
Yet this one seems very heavy on loadings in 16 bit games.
http://www.youtube.com/watch?v=FuDzQLx4wP4
and the 2nd game :
http://www.youtube.com/watch?v=pilO7GQLF9Q
Quote from: Devilmarkus on 13:16, 17 October 09
The developer dsk was destroyed by emulator. (No, I dont write the emulators name here, but it was not mine ;) )
Oh shit! Yes, this sounds like WinApe strikes again!
Any news about Elvira?
I would code for her!
Seriously, let's talk about the project. I think writting this in C would be better. I could make some nice structs and functions for all the game logic. It would be much easier than basic for me.
I am curious if I could help. If I do, it wil be a C project using SDCC. I am already familiar with SDCC and use a nice framework in Codeblocks that makes coding a bliss. It's a really good environment for writting game logic easilly and nicely. I guess I would still be able to call your RSX commands with this.
The problem is I am scared to get involved into this project right now. I am busy with a lot of other stuff, from CPC to real life stuff. But if we can go with this lightly it would be ok. Afterall it's a big project and it's gonna take some time. We could discuss about it by email too.
What do you think? Would it be ok if we migrate the project in C?
I wonder if it is possible to add a small C interpreter to BASIC as an RSX, then it would be possible to write programs that are a mixture of BASIC, C and machine code.
Quote from: steve on 16:54, 04 March 11
I wonder if it is possible to add a small C interpreter to BASIC as an RSX, then it would be possible to write programs that are a mixture of BASIC, C and machine code.
In case you like to use the wonderful Small C language for the CPC, then you can use Small C under CPC and with two special libraries you can use the program for Amsdos (IOLIB) and FutureOS (FiOLIB). All this stuff is uploaded to my FutureOS yahoo group. I haven't been able to use this nice things for quite a while, but it's worth taking a look at them.
EDIT: IMHO the best language for Elvira would be assembler. Reason: Save space!
.
Quote from: CPCLER on 09:48, 17 October 09
I am still not sure what you want:
Okay so if there are 150 distinct items... Each item can have 3 states:
Placed in a room.
In the players inventory.
Visible/Invisible.
This means the the object to room mapping and inventory will take up 1200 bytes.
This may have been addressed already but in my limited experience writing adventure games I would make room number zero = object taken. So if room number more than zero the object is not yet taken so not yet in inventory. Saves a few bytes i guess.
[edit] = yep, okay i see it's been mentioned already ;-)
8 bytes per item is total overkill. Back in the 80's the knew about packing stuff in.
defaultRoomNo - Where an item first occurs (needed for initialisation purposes)
- 1 byte needed to give up to 255 rooms, plus 0 if you want the player to start with the object.
RoomNo - Which room number the items is currently located (When not in the players inventory)
- 1 byte again, just using 0 as player inventory
taken - True/False (in the players inventory or not!)
- room # set as zero if taken, so no extra byte needed
visible - True/False(Visible to the player or not!)
- this is just 1 bit needed. If there are no more than 127 rooms, then the high bit of the room code can be used for visible/hidden flag, and we use 7 bits for the location instead of 8. I don't know if this flag is even needed though.
spriteAdr - Address of sprite date (Needed for displaying icon for item)
- assuming all sprites are the same size: this can be coded as 1 byte as well (for up to 256 items), just calculate sprite offset when needed based on memory location and size. the overhead will be minimal compared to drawing the sprites. But you know what? we can derive the index directly from the actual item's number in the item array. Hence, ordering the sprites the same as the objects removes the need for this value completely, since we can generate the sprite's image data location when needed from what we know.
So it's more like 2 bytes needed for the item table. If there are more than 255 rooms though it will take 4 bytes.
Guess that is no longer "active post" ? Could it be "unsticked" then ?
True.