├── Makefile ├── README.md ├── actor.s ├── actordata.s ├── ai.s ├── aligneddata.s ├── bg ├── names.txt ├── scorescr.chr ├── world.chr ├── world.map ├── world00.blc ├── world00.bli ├── world00.blk ├── world00.chr ├── world00.lva ├── world00.lvo ├── world00.map ├── world00.oba ├── worlddata.s ├── worldglobal.s └── worldinfo.s ├── boot.s ├── charset00.s ├── defines.s ├── eapi-am29f040-14.bin ├── efboot.s ├── example.d64 ├── example.seq ├── examplecart.seq ├── exampleef.crt ├── examplegmod2.crt ├── exomizer.s ├── file.s ├── gmod2boot.s ├── init.s ├── input.s ├── kernal.s ├── ldepack.s ├── ldepacksym.txt ├── level.s ├── loader.s ├── loadsym.txt ├── macros.s ├── main.s ├── math.s ├── memory.s ├── miscdata.s ├── music └── example.sng ├── panel.s ├── physics.s ├── playroutinedata.s ├── raster.s ├── screen.s ├── script00.s ├── sound.s ├── sounddata.s ├── spr ├── common.spr ├── common.spr.res ├── enemy.spr ├── enemy.spr.res ├── player.spr ├── player.spr.res └── spredit.cfg ├── sprite.s └── tools ├── Makefile ├── SDL.dll ├── bme.c ├── bme.h ├── bme_cfg.h ├── bme_err.h ├── bme_gfx.c ├── bme_gfx.h ├── bme_io.c ├── bme_io.h ├── bme_joy.c ├── bme_joy.h ├── bme_kbd.c ├── bme_kbd.h ├── bme_main.h ├── bme_map.c ├── bme_map.h ├── bme_mod.c ├── bme_mou.c ├── bme_mou.h ├── bme_raw.c ├── bme_s3m.c ├── bme_smp.c ├── bme_snd.c ├── bme_snd.h ├── bme_tbl.c ├── bme_tbl.h ├── bme_txt.c ├── bme_txt.h ├── bme_wav.c ├── bme_win.c ├── bme_win.h ├── bme_xm.c ├── bmeconv.c ├── bmeconv.exe ├── cp.bat ├── dasm.exe ├── dat2inc.c ├── dat2inc.exe ├── datafile.c ├── datafile.exe ├── editdata.c ├── editfont.lbm ├── editfont.spr ├── editio.h ├── editor.dat ├── editor.lbm ├── editor.pal ├── editor.spr ├── exomizer3.exe ├── fileio.c ├── fileio.h ├── filejoin.c ├── filejoin.exe ├── filelist.txt ├── filesplit.c ├── filesplit.exe ├── gcommon.h ├── gfxconv.c ├── gfxconv.exe ├── gt2mini.c ├── gt2mini.exe ├── maked64.c ├── maked64.exe ├── makeef.cpp ├── makeef.exe ├── makegmod2.cpp ├── makegmod2.exe ├── pack3.c ├── pack3.exe ├── pchunk3.c ├── pchunk3.exe ├── spred3.cpp ├── spred3.exe ├── stb_image_write.c ├── stb_image_write.h ├── symbols.c ├── symbols.exe ├── usecount.cpp ├── usecount.exe ├── worlded3.cpp └── worlded3.exe /Makefile: -------------------------------------------------------------------------------- 1 | all: example.d64 exampleef.crt examplegmod2.crt 2 | 3 | clean: 4 | del *.prg 5 | del *.pak 6 | del *.tbl 7 | del *sym.s 8 | del *.d64 9 | del *.crt 10 | 11 | example.d64: example.seq boot.prg loader.prg main.pak music00.pak level00.pak charset00.pak sprplayer.pak sprcommon.pak sprenemy.pak script00.pak 12 | maked64 example.d64 example.seq EXAMPLE_GAME______EG_2A 10 13 | 14 | exampleef.crt: example.d64 example.seq main.pak loadsym.s mainsymcart.s efboot.s 15 | dasm efboot.s -oefboot.bin -f3 16 | makeef efboot.bin examplecart.seq exampleef.bin 17 | cartconv -p -i exampleef.bin -o exampleef.crt -t easy 18 | 19 | examplegmod2.crt: example.d64 example.seq main.pak loadsym.s mainsymcart.s gmod2boot.s 20 | dasm gmod2boot.s -ogmod2boot.bin -f3 21 | makegmod2 gmod2boot.bin examplecart.seq examplegmod2-flash.bin examplegmod2-eeprom.bin 22 | cartconv -p -i examplegmod2-flash.bin -o examplegmod2.crt -t gmod2 23 | 24 | loader.prg: exomizer.s loader.s kernal.s memory.s 25 | dasm ldepack.s -oloader.prg -f3 -sldepack.tbl 26 | symbols ldepack.tbl ldepacksym.s ldepacksym.txt 27 | dasm loader.s -oloader.bin -f3 -sloader.tbl 28 | symbols loader.tbl loadsym.s loadsym.txt 29 | pack3 loader.bin loader.pak 30 | dasm ldepack.s -oloader.prg -f3 -sldepack.tbl 31 | 32 | boot.prg: boot.s kernal.s loader.prg 33 | dasm boot.s -oboot.prg 34 | 35 | main.pak: loader.prg memory.s defines.s main.s init.s input.s file.s screen.s raster.s math.s sound.s \ 36 | panel.s actor.s sprite.s physics.s level.s ai.s \ 37 | actordata.s sounddata.s aligneddata.s playroutinedata.s \ 38 | bg/worldinfo.s bg/scorescr.chr 39 | dasm main.s -omain.bin -smain.tbl -f3 40 | symbols main.tbl mainsym.s 41 | symbols main.tbl mainsymcart.s mainsymcart.txt 42 | pack3 main.bin main.pak 43 | 44 | music00.pak: music/example.sng 45 | gt2mini music/example.sng music00.s -ed000 46 | dasm music00.s -omusic00.prg -p3 47 | exomizer3 level -M256 -f -c -omusic00.pak music00.prg 48 | 49 | level00.pak: bg/world00.map bg/world00.lvo bg/world00.lva 50 | pchunk3 bg/world00.map level00map.pak 51 | filejoin bg/world00.lvo+bg/world00.lva level00data.bin 52 | pack3 level00data.bin level00data.pak 53 | filejoin level00map.pak+level00data.pak level00.pak 54 | 55 | charset00.pak: charset00.s mainsym.s memory.s bg/world00.blk bg/world00.bli bg/world00.chr bg/world00.oba 56 | dasm charset00.s -ocharset00.bin -f3 57 | pack3 charset00.bin charset00.pak 58 | 59 | sprcommon.pak: spr/common.spr.res 60 | pchunk3 spr/common.spr.res sprcommon.pak 61 | 62 | sprplayer.pak: spr/player.spr.res 63 | pchunk3 spr/player.spr.res sprplayer.pak 64 | 65 | sprenemy.pak: spr/enemy.spr.res 66 | pchunk3 spr/enemy.spr.res sprenemy.pak 67 | 68 | script00.pak: script00.s mainsym.s macros.s memory.s 69 | dasm script00.s -oscript00.bin -f3 70 | pchunk3 script00.bin script00.pak -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cadaver/c64gameframework/15eaa821599c860ab94009085d6b340f93f65670/README.md -------------------------------------------------------------------------------- /actordata.s: -------------------------------------------------------------------------------- 1 | ACT_NONE = 0 2 | ACT_PLAYER = 1 3 | ACT_ITEM = 2 4 | ACT_BULLET = 3 5 | ACT_SMOKECLOUD = 4 6 | ACT_EXPLOSION = 5 7 | ACT_ENEMY = 6 8 | 9 | actDataTblLo: dc.b actPlayer 17 | dc.b >actItem 18 | dc.b >actBullet 19 | dc.b >actSmokeCloud 20 | dc.b >actExplosion 21 | dc.b >actEnemy 22 | 23 | actBottomAdjustTbl: 24 | dc.b -2 25 | dc.b -1 26 | dc.b -1 27 | dc.b -1 28 | dc.b -1 29 | dc.b -1 30 | 31 | actPlayer: dc.b GRP_HEROES|AF_NOREMOVECHECK ;Flags 32 | dc.b 100 ;Initial health 33 | dc.w $0000+USESCRIPT ;Update routine, script entrypoint or address in inbuilt engine code (< $8000) 34 | dc.w $0001+USESCRIPT ;Draw routine, script entrypoint or address in inbuilt engine code (< $8000) 35 | dc.b 7 ;Gravity acceleration 36 | dc.b $40 ;Side collision offset 37 | dc.b -2 ;Top collision offset 38 | dc.b NO_MODIFY ;Received damage mod 39 | dc.w $0002+USESCRIPT ;Damage response routine, script entrypoint or address in inbuilt engine code (< $8000) 40 | 41 | actItem: dc.b 0 ;Flags 42 | dc.b 0 ;Health (= default pickup) 43 | dc.w $0003+USESCRIPT ;Update routine 44 | dc.w $0004+USESCRIPT ;Draw routine 45 | dc.b 7 ;Gravity 46 | dc.b $10 ;Side collision offset 47 | dc.b 0 ;Top collision offset 48 | 49 | actBullet: dc.b 0 ;Flags 50 | dc.b 5 ;Initial health (damage for bullets) 51 | dc.w $0005+USESCRIPT ;Update routine 52 | dc.w $0006+USESCRIPT ;Draw routine 53 | 54 | actSmokeCloud: dc.b 0 ;Flags 55 | dc.b 0 ;Initial health 56 | dc.w $0007+USESCRIPT ;Update routine 57 | dc.w $0008+USESCRIPT ;Draw routine 58 | 59 | actExplosion: dc.b 0 ;Flags 60 | dc.b 0 ;Initial health 61 | dc.w $0009+USESCRIPT ;Update routine 62 | dc.w $000a+USESCRIPT ;Draw routine 63 | 64 | actEnemy: dc.b GRP_ENEMIES|AF_NOREMOVECHECK ;Flags 65 | dc.b 15 ;Initial health 66 | dc.w $000b+USESCRIPT ;Update routine, script entrypoint or address in inbuilt engine code (< $8000) 67 | dc.w $000c+USESCRIPT ;Draw routine, script entrypoint or address in inbuilt engine code (< $8000) 68 | dc.b 5 ;Gravity acceleration (reduced compared to player) 69 | dc.b $60 ;Side collision offset 70 | dc.b -1 ;Top collision offset 71 | dc.b NO_MODIFY ;Received damage mod 72 | dc.w $000d+USESCRIPT ;Damage response routine -------------------------------------------------------------------------------- /bg/names.txt: -------------------------------------------------------------------------------- 1 | ; Actor names 2 | PLAYER 3 | ITEM 4 | BULLET 5 | SMOKECLOUD 6 | EXPLOSION 7 | ENEMY 8 | end 9 | ; Item names 10 | HEALTH 11 | AMMO 12 | end 13 | -------------------------------------------------------------------------------- /bg/scorescr.chr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cadaver/c64gameframework/15eaa821599c860ab94009085d6b340f93f65670/bg/scorescr.chr -------------------------------------------------------------------------------- /bg/world.chr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cadaver/c64gameframework/15eaa821599c860ab94009085d6b340f93f65670/bg/world.chr -------------------------------------------------------------------------------- /bg/world.map: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cadaver/c64gameframework/15eaa821599c860ab94009085d6b340f93f65670/bg/world.map -------------------------------------------------------------------------------- /bg/world00.blc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cadaver/c64gameframework/15eaa821599c860ab94009085d6b340f93f65670/bg/world00.blc -------------------------------------------------------------------------------- /bg/world00.bli: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cadaver/c64gameframework/15eaa821599c860ab94009085d6b340f93f65670/bg/world00.bli -------------------------------------------------------------------------------- /bg/world00.blk: -------------------------------------------------------------------------------- 1 |  (+H[hhhhhxx 2 | 3 |  8;XkhhhhhKKh +hh(H hxx[h ;hh8X 4 | 5 | hKKk -------------------------------------------------------------------------------- /bg/world00.chr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cadaver/c64gameframework/15eaa821599c860ab94009085d6b340f93f65670/bg/world00.chr -------------------------------------------------------------------------------- /bg/world00.lva: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cadaver/c64gameframework/15eaa821599c860ab94009085d6b340f93f65670/bg/world00.lva -------------------------------------------------------------------------------- /bg/world00.lvo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cadaver/c64gameframework/15eaa821599c860ab94009085d6b340f93f65670/bg/world00.lvo -------------------------------------------------------------------------------- /bg/world00.map: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cadaver/c64gameframework/15eaa821599c860ab94009085d6b340f93f65670/bg/world00.map -------------------------------------------------------------------------------- /bg/world00.oba: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cadaver/c64gameframework/15eaa821599c860ab94009085d6b340f93f65670/bg/world00.oba -------------------------------------------------------------------------------- /bg/worlddata.s: -------------------------------------------------------------------------------- 1 | 2 | lvlActBitStart: 3 | dc.b 0 4 | dc.b 2 5 | 6 | lvlObjBitStart: 7 | dc.b 2 8 | dc.b 2 9 | -------------------------------------------------------------------------------- /bg/worldglobal.s: -------------------------------------------------------------------------------- 1 | 2 | globalActX: 3 | dc.b $00 4 | dc.b $00 5 | dc.b $00 6 | dc.b $00 7 | dc.b $00 8 | dc.b $00 9 | dc.b $00 10 | dc.b $00 11 | dc.b $00 12 | dc.b $00 13 | dc.b $00 14 | dc.b $00 15 | dc.b $00 16 | dc.b $00 17 | dc.b $00 18 | dc.b $00 19 | dc.b $00 20 | dc.b $00 21 | dc.b $00 22 | dc.b $00 23 | dc.b $00 24 | dc.b $00 25 | dc.b $00 26 | dc.b $00 27 | dc.b $00 28 | dc.b $00 29 | dc.b $00 30 | dc.b $00 31 | dc.b $00 32 | dc.b $00 33 | dc.b $00 34 | dc.b $00 35 | 36 | globalActY: 37 | dc.b $00 38 | dc.b $00 39 | dc.b $00 40 | dc.b $00 41 | dc.b $00 42 | dc.b $00 43 | dc.b $00 44 | dc.b $00 45 | dc.b $00 46 | dc.b $00 47 | dc.b $00 48 | dc.b $00 49 | dc.b $00 50 | dc.b $00 51 | dc.b $00 52 | dc.b $00 53 | dc.b $00 54 | dc.b $00 55 | dc.b $00 56 | dc.b $00 57 | dc.b $00 58 | dc.b $00 59 | dc.b $00 60 | dc.b $00 61 | dc.b $00 62 | dc.b $00 63 | dc.b $00 64 | dc.b $00 65 | dc.b $00 66 | dc.b $00 67 | dc.b $00 68 | dc.b $00 69 | 70 | globalActZ: 71 | dc.b $00 72 | dc.b $00 73 | dc.b $00 74 | dc.b $00 75 | dc.b $00 76 | dc.b $00 77 | dc.b $00 78 | dc.b $00 79 | dc.b $00 80 | dc.b $00 81 | dc.b $00 82 | dc.b $00 83 | dc.b $00 84 | dc.b $00 85 | dc.b $00 86 | dc.b $00 87 | dc.b $00 88 | dc.b $00 89 | dc.b $00 90 | dc.b $00 91 | dc.b $00 92 | dc.b $00 93 | dc.b $00 94 | dc.b $00 95 | dc.b $00 96 | dc.b $00 97 | dc.b $00 98 | dc.b $00 99 | dc.b $00 100 | dc.b $00 101 | dc.b $00 102 | dc.b $00 103 | 104 | globalActT: 105 | dc.b $00 106 | dc.b $00 107 | dc.b $00 108 | dc.b $00 109 | dc.b $00 110 | dc.b $00 111 | dc.b $00 112 | dc.b $00 113 | dc.b $00 114 | dc.b $00 115 | dc.b $00 116 | dc.b $00 117 | dc.b $00 118 | dc.b $00 119 | dc.b $00 120 | dc.b $00 121 | dc.b $00 122 | dc.b $00 123 | dc.b $00 124 | dc.b $00 125 | dc.b $00 126 | dc.b $00 127 | dc.b $00 128 | dc.b $00 129 | dc.b $00 130 | dc.b $00 131 | dc.b $00 132 | dc.b $00 133 | dc.b $00 134 | dc.b $00 135 | dc.b $00 136 | dc.b $00 137 | dc.b $00 138 | 139 | globalActWpn: 140 | dc.b $00 141 | dc.b $00 142 | dc.b $00 143 | dc.b $00 144 | dc.b $00 145 | dc.b $00 146 | dc.b $00 147 | dc.b $00 148 | dc.b $00 149 | dc.b $00 150 | dc.b $00 151 | dc.b $00 152 | dc.b $00 153 | dc.b $00 154 | dc.b $00 155 | dc.b $00 156 | dc.b $00 157 | dc.b $00 158 | dc.b $00 159 | dc.b $00 160 | dc.b $00 161 | dc.b $00 162 | dc.b $00 163 | dc.b $00 164 | dc.b $00 165 | dc.b $00 166 | dc.b $00 167 | dc.b $00 168 | dc.b $00 169 | dc.b $00 170 | dc.b $00 171 | dc.b $00 172 | 173 | globalActOrg: 174 | dc.b $00 175 | dc.b $00 176 | dc.b $00 177 | dc.b $00 178 | dc.b $00 179 | dc.b $00 180 | dc.b $00 181 | dc.b $00 182 | dc.b $00 183 | dc.b $00 184 | dc.b $00 185 | dc.b $00 186 | dc.b $00 187 | dc.b $00 188 | dc.b $00 189 | dc.b $00 190 | dc.b $00 191 | dc.b $00 192 | dc.b $00 193 | dc.b $00 194 | dc.b $00 195 | dc.b $00 196 | dc.b $00 197 | dc.b $00 198 | dc.b $00 199 | dc.b $00 200 | dc.b $00 201 | dc.b $00 202 | dc.b $00 203 | dc.b $00 204 | dc.b $00 205 | dc.b $00 206 | -------------------------------------------------------------------------------- /bg/worldinfo.s: -------------------------------------------------------------------------------- 1 | NUMLEVELS = 1 2 | NUMZONES = 2 3 | WORLDSIZEBLOCKS = 1995 4 | WORLDSIZESCREENS = 9 5 | LEVELACTBITSIZE = 2 6 | LEVELOBJBITSIZE = 0 7 | ZONEBITSIZE = 1 8 | -------------------------------------------------------------------------------- /boot.s: -------------------------------------------------------------------------------- 1 | ; Autostarting bootpart 2 | 3 | 4 | processor 6502 5 | 6 | include memory.s 7 | include kernal.s 8 | include loadsym.s 9 | include ldepacksym.s 10 | 11 | org $032a 12 | 13 | dc.b $0b,$08 ;GETIN vector or BASIC next line address 14 | dc.w AutoStart ;CLALL vector or BASIC line number 15 | dc.b $9e,$32,$30,$36,$31 ;Sys instruction 16 | dc.b $00,$00,$00 17 | 18 | rorg $080d 19 | 20 | BasicStart: lda #<(BootStart-AutoStart+BasicEnd-1) 21 | sta BasicEnd+3 22 | lda #>(BootStart-AutoStart+BasicEnd-1) 23 | sta BasicEnd+4 24 | BasicEnd: 25 | rend 26 | 27 | AutoStart: ldx #BootEnd-BootStart 28 | CopyBoot: lda BootStart-1,x 29 | sta.wx $0100-1,x 30 | dex 31 | bne CopyBoot 32 | jmp $0100 33 | 34 | BootStart: 35 | rorg $0100 36 | 37 | BootWaitBottom: lda $d011 ;Wait for bottom to smooth the transition 38 | bpl BootWaitBottom 39 | lda #$00 40 | sta $d015 41 | sta $d020 42 | sta $d021 43 | tax 44 | ldy #$84 45 | sty $d018 46 | dey 47 | ClearScreen: sta $d800,x 48 | inx 49 | bne ClearScreen 50 | inc ClearScreen+2 51 | dey 52 | bmi ClearScreen 53 | sei 54 | sty $dc0d ;Disable & acknowledge IRQ sources (Y=$7f) 55 | lda $dc0d 56 | lda #NMI 59 | sta $0319 60 | lda #$81 ;Run CIA2 Timer A once to disable NMI from Restore keypress 61 | sta $dd0d ;Timer A interrupt source 62 | lda #$01 ;Timer A count ($0001) 63 | sta $dd04 64 | stx $dd05 65 | lda #%00011001 ;Run Timer A in one-shot mode 66 | sta $dd0e 67 | lda #$06 68 | ldx #loaderFileName 70 | jsr SetNam 71 | lda #$02 72 | ldx $ba ;Use last used device 73 | ldy #$00 74 | jsr SetLFS 75 | jsr Open 76 | ldx #$02 ;Open file $02 for input 77 | jsr ChkIn 78 | ldx #36 79 | ShowMessage: lda #$0f 80 | sta colors+12*40+1,x 81 | lda message-1,x 82 | and #$3f 83 | sta $2000+12*40+1,x 84 | dex 85 | bne ShowMessage 86 | LoadExomizer: jsr ChrIn ;Load Exomizer (unpacked) 87 | sta exomizerCodeStart,x 88 | inx 89 | cpx #(ldepackCodeEnd-exomizerCodeStart) 90 | bne LoadExomizer 91 | lda #>(InitLoader-1) ;Have to push entrypoint to stack as this code will be overwritten 92 | pha 93 | lda #<(InitLoader-1) 94 | pha 95 | lda #ldepackCodeEnd 97 | jmp Depack 98 | NMI: rti 99 | 100 | message: dc.b "HOLD SPACE/FIRE FOR SAFE MODE " 101 | loaderFileName: dc.b "LOADER" 102 | messageEnd: 103 | 104 | rend 105 | BootEnd: -------------------------------------------------------------------------------- /charset00.s: -------------------------------------------------------------------------------- 1 | processor 6502 2 | 3 | include memory.s 4 | include mainsym.s 5 | 6 | org blkTL 7 | incbin bg/world00.blk 8 | 9 | org chars 10 | incbin bg/world00.chr 11 | 12 | org blkInfo 13 | incbin bg/world00.bli 14 | 15 | org blkColors 16 | incbin bg/world00.blc 17 | 18 | org lvlObjAnimFrames 19 | incbin bg/world00.oba 20 | 21 | org charAnimCodeJump 22 | rts 23 | 24 | -------------------------------------------------------------------------------- /defines.s: -------------------------------------------------------------------------------- 1 | ; Defines that affect the memory map 2 | 3 | MAX_SPR = 24 4 | MAX_CACHESPRITES = 64 5 | MAX_CHUNKFILES = 64 6 | MAX_MAPROWS = 64 7 | MAX_LVLACT = 96 8 | MAX_LVLOBJ = 96 9 | MAX_SAVEACT = 32 10 | MAX_ZONEOBJ = 15 11 | MAX_ACT = 20 12 | MAX_COMPLEXACT = 6 13 | MAX_BOUNDS = 32 14 | MAX_NAVAREAS = 48 15 | MAX_ACTX = 26 16 | MAX_ACTY = 19 17 | 18 | ACTI_PLAYER = 0 19 | ACTI_FIRSTNPC = 1 20 | ACTI_LASTNPC = MAX_COMPLEXACT-1 21 | ACTI_FIRSTNONNPC = MAX_COMPLEXACT 22 | ACTI_LAST = MAX_ACT-1 23 | 24 | SCROLLROWS = 23 25 | USETURBOMODE = 1 ;Use C128 & SuperCPU turbo mode 26 | 27 | -------------------------------------------------------------------------------- /eapi-am29f040-14.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cadaver/c64gameframework/15eaa821599c860ab94009085d6b340f93f65670/eapi-am29f040-14.bin -------------------------------------------------------------------------------- /example.d64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cadaver/c64gameframework/15eaa821599c860ab94009085d6b340f93f65670/example.d64 -------------------------------------------------------------------------------- /example.seq: -------------------------------------------------------------------------------- 1 | ; File directory order 2 | boot.prg EXAMPLE 3 | loader.prg LOADER 4 | main.pak 00 5 | music00.pak 01 6 | charset00.pak 02 7 | level00.pak 03 8 | sprcommon.pak 04 9 | sprplayer.pak 05 10 | sprenemy.pak 06 11 | script00.pak 07 -------------------------------------------------------------------------------- /examplecart.seq: -------------------------------------------------------------------------------- 1 | main.pak 00 2 | music00.pak 01 3 | charset00.pak 02 4 | level00.pak 03 5 | sprcommon.pak 04 6 | sprplayer.pak 05 7 | sprenemy.pak 06 8 | script00.pak 07 -------------------------------------------------------------------------------- /exampleef.crt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cadaver/c64gameframework/15eaa821599c860ab94009085d6b340f93f65670/exampleef.crt -------------------------------------------------------------------------------- /examplegmod2.crt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cadaver/c64gameframework/15eaa821599c860ab94009085d6b340f93f65670/examplegmod2.crt -------------------------------------------------------------------------------- /exomizer.s: -------------------------------------------------------------------------------- 1 | tablBi = depackBuffer 2 | tablLo = depackBuffer + 52 3 | tablHi = depackBuffer + 104 4 | 5 | FORWARD_DECRUNCHING = 1 6 | LITERAL_SEQUENCES_NOT_USED = 1 7 | MAX_SEQUENCE_LENGTH_256 = 1 8 | 9 | ; ------------------------------------------------------------------- 10 | ; This source code is altered and is not the original version found on 11 | ; the Exomizer homepage. Forward decrunching modifications improved 12 | ; based on the version in Krill's loader. 13 | ; ------------------------------------------------------------------- 14 | ; 15 | ; Copyright (c) 2002 - 2018 Magnus Lind. 16 | ; 17 | ; This software is provided 'as-is', without any express or implied warranty. 18 | ; In no event will the authors be held liable for any damages arising from 19 | ; the use of this software. 20 | ; 21 | ; Permission is granted to anyone to use this software for any purpose, 22 | ; including commercial applications, and to alter it and redistribute it 23 | ; freely, subject to the following restrictions: 24 | ; 25 | ; 1. The origin of this software must not be misrepresented; you must not 26 | ; claim that you wrote the original software. If you use this software in a 27 | ; product, an acknowledgment in the product documentation would be 28 | ; appreciated but is not required. 29 | ; 30 | ; 2. Altered source versions must be plainly marked as such, and must not 31 | ; be misrepresented as being the original software. 32 | ; 33 | ; 3. This notice may not be removed or altered from any distribution. 34 | ; 35 | ; 4. The names of this software and/or it's copyright holders may not be 36 | ; used to endorse or promote products derived from this software without 37 | ; specific prior written permission. 38 | ; 39 | ; ------------------------------------------------------------------- 40 | ; no code below this comment has to be modified in order to generate 41 | ; a working decruncher of this source file. 42 | ; However, you may want to relocate the tables last in the file to a 43 | ; more suitable address. 44 | ; ------------------------------------------------------------------- 45 | 46 | ; Depack from file stream packed with Exomizer 3 forward mode 47 | ; 48 | ; Parameters: A,X load address 49 | ; Returns: - 50 | ; Modifies: A,X,Y 51 | 52 | Depack: sta zpDestLo 53 | stx zpDestHi 54 | DepackDestSet: 55 | ; ------------------------------------------------------------------- 56 | ; jsr this label to decrunch, it will in turn init the tables and 57 | ; call the decruncher 58 | ; no constraints on register content, however the 59 | ; decimal flag has to be #0 (it almost always is, otherwise do a cld) 60 | ; init zeropage, x and y regs. (12 bytes) 61 | ; 62 | jsr GetByte 63 | sta zpBitBuf 64 | ldy #0 65 | ; ------------------------------------------------------------------- 66 | ; calculate tables (62 bytes) + get_bits macro 67 | ; x and y must be #0 when entering 68 | ; 69 | clc 70 | table_gen: 71 | tax 72 | tya 73 | and #$0f 74 | sta tablLo,y 75 | beq shortcut ; start a new sequence 76 | ; ------------------------------------------------------------------- 77 | txa 78 | adc tablLo - 1,y 79 | sta tablLo,y 80 | lda zpLenHi 81 | adc tablHi - 1,y 82 | shortcut: 83 | sta tablHi,y 84 | ; ------------------------------------------------------------------- 85 | lda #$01 86 | sta zpLenHi 87 | lda #$78 ; %01111000 88 | jsr get_bits 89 | ; ------------------------------------------------------------------- 90 | lsr 91 | tax 92 | beq rolled 93 | php 94 | rolle: 95 | asl zpLenHi 96 | sec 97 | ror 98 | dex 99 | bne rolle 100 | plp 101 | rolled: 102 | ror 103 | sta tablBi,y 104 | bmi no_fixup_lohi 105 | lda zpLenHi 106 | stx zpLenHi 107 | skip1 108 | no_fixup_lohi: 109 | txa 110 | ; ------------------------------------------------------------------- 111 | iny 112 | cpy #52 113 | bne table_gen 114 | ; ------------------------------------------------------------------- 115 | ; prepare for main decruncher 116 | ldy zpDestLo 117 | stx zpDestLo 118 | stx zpBitsHi 119 | 120 | ; ------------------------------------------------------------------- 121 | ; copy one literal byte to destination (11 bytes) 122 | ; 123 | literal_start1: 124 | if FORWARD_DECRUNCHING = 0 125 | tya 126 | bne no_hi_decr 127 | dec zpDestHi 128 | no_hi_decr: 129 | dey 130 | endif 131 | jsr GetByte 132 | sta (zpDestLo),y 133 | if FORWARD_DECRUNCHING > 0 134 | iny 135 | bne no_hi_incr 136 | inc zpDestHi 137 | no_hi_incr: 138 | endif 139 | ; ------------------------------------------------------------------- 140 | ; fetch sequence length index (15 bytes) 141 | ; x must be #0 when entering and contains the length index + 1 142 | ; when exiting or 0 for literal byte 143 | next_round: 144 | dex 145 | lda zpBitBuf 146 | no_literal1: 147 | asl 148 | bne nofetch8 149 | jsr GetByte 150 | rol 151 | nofetch8: 152 | inx 153 | bcc no_literal1 154 | sta zpBitBuf 155 | ; ------------------------------------------------------------------- 156 | ; check for literal byte (2 bytes) 157 | ; 158 | beq literal_start1 159 | ; ------------------------------------------------------------------- 160 | ; check for decrunch done and literal sequences (4 bytes) 161 | ; 162 | cpx #$11 163 | bcs exit_or_lit_seq 164 | 165 | ; ------------------------------------------------------------------- 166 | ; calulate length of sequence (zp_len) (18(11) bytes) + get_bits macro 167 | ; 168 | lda.wx tablBi - 1,x 169 | jsr get_bits 170 | adc tablLo - 1,x ; we have now calculated zpLenLo 171 | sta zpLenLo 172 | if MAX_SEQUENCE_LENGTH_256 = 0 173 | lda zpBitsHi 174 | adc tablHi - 1,x ; c = 0 after this. 175 | sta zpLenHi 176 | ; ------------------------------------------------------------------- 177 | ; here we decide what offset table to use (27(26) bytes) + get_bits_nc macro 178 | ; z-flag reflects zpLenHi here 179 | ; 180 | ldx zpLenLo 181 | else 182 | tax 183 | endif 184 | lda #$e1 185 | cpx #$03 186 | bcs gbnc2_next 187 | lda tablBit,x 188 | gbnc2_next: 189 | asl zpBitBuf 190 | bne gbnc2_ok 191 | tax 192 | jsr GetByte 193 | rol 194 | sta zpBitBuf 195 | txa 196 | gbnc2_ok: 197 | rol 198 | bcs gbnc2_next 199 | tax 200 | ; ------------------------------------------------------------------- 201 | ; calulate absolute offset (zp_src) (21 bytes) + get_bits macro 202 | ; 203 | if MAX_SEQUENCE_LENGTH_256 = 0 204 | lda #0 205 | sta zpBitsHi 206 | endif 207 | if FORWARD_DECRUNCHING = 0 208 | lda tablBi,x 209 | jsr get_bits 210 | adc tablLo,x 211 | sta zpSrcLo 212 | lda zpBitsHi 213 | adc tablHi,x 214 | adc zpDestHi 215 | sta zpSrcHi 216 | else 217 | lda tablBi,x 218 | jsr get_bits 219 | clc 220 | adc tablLo,x 221 | eor #$ff 222 | sta zpSrcLo 223 | lda zpBitsHi 224 | adc tablHi,x 225 | eor #$ff 226 | adc zpDestHi 227 | sta zpSrcHi 228 | endif 229 | 230 | ; ------------------------------------------------------------------- 231 | ; prepare for copy loop (2 bytes) 232 | ; 233 | pre_copy: 234 | ldx zpLenLo 235 | ; ------------------------------------------------------------------- 236 | ; main copy loop (30 bytes) 237 | ; 238 | copy_next: 239 | if FORWARD_DECRUNCHING = 0 240 | tya 241 | bne copy_skip_hi 242 | dec zpDestHi 243 | dec zpSrcHi 244 | copy_skip_hi: 245 | dey 246 | endif 247 | if LITERAL_SEQUENCES_NOT_USED = 0 248 | if FORWARD_DECRUNCHING > 0 249 | bcc get_literal_byte 250 | else 251 | bcs get_literal_byte 252 | endif 253 | endif 254 | lda (zpSrcLo),y 255 | literal_byte_gotten: 256 | sta (zpDestLo),y 257 | if FORWARD_DECRUNCHING > 0 258 | iny 259 | bne copy_skip_hi 260 | inc zpDestHi 261 | inc zpSrcHi 262 | copy_skip_hi: 263 | endif 264 | dex 265 | bne copy_next 266 | if MAX_SEQUENCE_LENGTH_256 = 0 267 | lda zpLenHi 268 | endif 269 | begin_stx: 270 | stx zpBitsHi 271 | if (FORWARD_DECRUNCHING > 0 && MAX_SEQUENCE_LENGTH_256 = 0 && LITERAL_SEQUENCES_NOT_USED = 0) 272 | bne no_next_round 273 | jmp next_round 274 | no_next_round: 275 | else 276 | beq next_round 277 | endif 278 | if MAX_SEQUENCE_LENGTH_256 = 0 279 | copy_next_hi: 280 | dec zpLenHi 281 | jmp copy_next 282 | endif 283 | if LITERAL_SEQUENCES_NOT_USED = 0 284 | get_literal_byte: 285 | jsr GetByte 286 | if FORWARD_DECRUNCHING > 0 287 | bcc literal_byte_gotten 288 | else 289 | sec 290 | bcs literal_byte_gotten 291 | endif 292 | endif 293 | ; ------------------------------------------------------------------- 294 | ; exit or literal sequence handling (16(12) bytes) 295 | ; 296 | if LITERAL_SEQUENCES_NOT_USED = 0 297 | exit_or_lit_seq: 298 | beq decr_exit 299 | jsr GetByte 300 | if MAX_SEQUENCE_LENGTH_256 = 0 301 | sta zpLenHi 302 | endif 303 | jsr GetByte 304 | tax 305 | if FORWARD_DECRUNCHING > 0 306 | clc 307 | bcc copy_next 308 | else 309 | sec 310 | bcs copy_next 311 | endif 312 | decr_exit: 313 | endif 314 | rts 315 | 316 | ; ------------------------------------------------------------------- 317 | ; get bits from stream 318 | ; 319 | get_bits: 320 | adc #$80 ; needs c=0, affects v 321 | asl 322 | bpl gb_skip 323 | gb_next: 324 | asl zpBitBuf 325 | bne gb_ok 326 | pha 327 | jsr GetByte 328 | rol 329 | sta zpBitBuf 330 | pla 331 | gb_ok: 332 | rol 333 | bmi gb_next 334 | gb_skip: 335 | bvc gb_get_done 336 | sta zpBitsHi 337 | jsr GetByte 338 | sec 339 | if LITERAL_SEQUENCES_NOT_USED > 0 340 | exit_or_lit_seq: 341 | endif 342 | gb_get_done: 343 | rts 344 | 345 | ; ------------------------------------------------------------------- 346 | ; the static stable used for bits+offset for lengths 3, 1 and 2 (3 bytes) 347 | ; bits 4, 2, 4 and offsets 16, 48, 32 348 | tablBit: 349 | dc.b %11100001, %10001100, %11100010 350 | 351 | ; ------------------------------------------------------------------- 352 | ; end of decruncher 353 | ; ------------------------------------------------------------------- 354 | -------------------------------------------------------------------------------- /init.s: -------------------------------------------------------------------------------- 1 | org fileAreaStart 2 | 3 | ; Initialize registers/variables at startup. This code is called only once and can be 4 | ; disposed after that. 5 | ; 6 | ; Parameters: - 7 | ; Returns: - 8 | ; Modifies: A,X,Y,temp vars 9 | 10 | InitAll: sei 11 | 12 | ; Setup preparations for loading 13 | 14 | lda loaderMode 15 | beq IA_UseSafeMode 16 | bpl InitZeroPage 17 | IA_UseFastLoad: lda #SetSpriteRange 20 | sta FL_SetSpriteRangeJsr+2 21 | bne InitZeroPage 22 | IA_UseSafeMode: ldx #stopIrqCodeEnd-stopIrqCode-1 ;Safe mode: setup screen blanking on load begin 23 | IA_CopyStopIrqCode: 24 | lda stopIrqCode,x 25 | sta StopIrq,x 26 | dex 27 | bpl IA_CopyStopIrqCode 28 | 29 | ; Initialize other zeropage values 30 | 31 | InitZeroPage: lda #fileAreaStart 34 | sta freeMemHi 35 | lda #>fileAreaEnd 36 | sta musicDataHi 37 | sta zoneBufferHi 38 | lda #38 39 | sta textRightMargin 40 | lda #1 41 | sta cacheFrame 42 | lda #NO_LEVEL 43 | sta levelNum 44 | sta autoDeactObj 45 | lda #$00 46 | sta textLeftMargin 47 | sta musicDataLo 48 | sta zoneBufferLo 49 | sta newFrameFlag 50 | sta drawScreenFlag 51 | sta firstSortSpr 52 | sta numSpr 53 | sta nextLvlActIndex 54 | sta textTime 55 | sta frameNumber 56 | sta dsTopPtrLo 57 | sta dsBottomPtrLo 58 | 59 | jsr WaitBottom 60 | lda #$0b ;Blank screen now 61 | sta $d011 62 | 63 | ; Initialize video + SID registers 64 | 65 | InitVideo: lda #$00 66 | sta $d01b ;Sprites on top of BG 67 | sta $d01d ;Sprite X-expand off 68 | sta $d017 ;Sprite Y-expand off 69 | sta $d020 70 | sta $d026 ;Set sprite multicolor 2 71 | sta $d415 ;Filter lowbyte for all subsequent music 72 | lda $dd00 ;Only videobank 0 supported due to the disk fastloader 73 | and #$fc 74 | sta $dd00 75 | lda #$ff-$40 ;Init reading joystick + select reading port 2 paddles for 2nd firebutton 76 | sta $dc00 77 | lda #$01 78 | sta $d025 ;Set sprite multicolor 1 79 | lda #$ff ;Set all sprites multicolor 80 | sta $d01c 81 | ldx #$10 82 | IV_SpriteY: dex 83 | dex 84 | sta $d001,x 85 | bne IV_SpriteY 86 | sta $d015 ;All sprites on and to the bottom 87 | jsr WaitBottom ;(some C64's need to "warm up" sprites 88 | ;to avoid one frame flash when they're 89 | stx $d015 ;actually used for the first time) 90 | 91 | ; SID detection from http://codebase64.org/doku.php?id=base:detecting_sid_type_-_safe_method 92 | 93 | lda #$ff ;Set frequency in voice 3 to $ffff 94 | sta $d412 ;...and set testbit (other bits doesn't matter) in $d412 to disable oscillator 95 | sta $d40e 96 | sta $d40f 97 | lda #$20 ;Sawtooth wave and gatebit OFF to start oscillator again. 98 | sta $d412 99 | lda $d41b ;Accu now has different value depending on sid model (6581=3/8580=2) 100 | cmp #$02 ;If result out of bounds, it's fast emu or something; use 6581 code (skip filter modify) 101 | beq SIDDetect_8580 102 | SIDDetect_6581: lda #$4c 103 | sta Play_ModifyCutoff8580 104 | lda #Play_CutoffOK 107 | sta Play_ModifyCutoff8580+2 108 | SIDDetect_8580: 109 | 110 | ; Init text charset + clear panel screen RAM 111 | 112 | InitPanelChars: ldy #$04 113 | IPC_Loop: lda panelCharData,x 114 | IPC_Sta: sta panelChars,x 115 | inx 116 | bne IPC_Loop 117 | inc IPC_Loop+2 118 | inc IPC_Sta+2 119 | dey 120 | bne IPC_Loop 121 | ldx #79 122 | IPC_PanelScreenLoop: 123 | lda #$20 124 | sta panelScreen+22*40,x 125 | lda #$00 126 | sta colors+22*40,x 127 | dex 128 | bpl IPC_PanelScreenLoop 129 | ldx #$07 130 | IPC_PanelSpriteLoop: 131 | lda #(emptySprite-videoBank)/$40 132 | sta panelScreen+$3f8,x 133 | dex 134 | bpl IPC_PanelSpriteLoop 135 | lda #$60 ;Prevent crash if charset animation attempted without charset 136 | sta charAnimCodeJump 137 | 138 | ; Initialize sprite cache variables + the empty sprite 139 | 140 | ldx #$3f 141 | ISprC_Loop: lda #$ff 142 | sta cacheSprFile,x 143 | lda #$00 144 | sta cacheSprAge,x 145 | sta emptySprite,x 146 | dex 147 | bpl ISprC_Loop 148 | 149 | ; Initialize resources 150 | 151 | ldx #MAX_CHUNKFILES 152 | IR_Loop: sta fileHi,x 153 | sta fileAge,x 154 | dex 155 | bpl IR_Loop 156 | 157 | ; Initialize sprite multiplexing order & sprite Y coords 158 | 159 | InitSprites: ldx #MAX_SPR 160 | ISpr_Loop: txa 161 | sta sprOrder,x 162 | lda #$ff 163 | sta sprY,x 164 | dex 165 | bpl ISpr_Loop 166 | 167 | ; Initialize PAL/NTSC differences 168 | 169 | ldx #<((IRQ3_LINE-IRQ1_LINE)*63) 170 | ldy #>((IRQ3_LINE-IRQ1_LINE)*63) 171 | lda ntscFlag 172 | beq IA_IsPAL 173 | ldx #<((IRQ3_LINE-IRQ1_LINE)*65) 174 | ldy #>((IRQ3_LINE-IRQ1_LINE)*65) 175 | IA_IsPAL: stx Irq1_TimerCountLo+1 176 | sty Irq1_TimerCountHi+1 177 | if USETURBOMODE > 0 178 | lda $d030 ;Enable IRQ code for turbo switching for C128 & SCPU 179 | cmp #$ff 180 | bne IA_UseTurbo 181 | lda $d0bc 182 | bmi IA_NoTurbo 183 | IA_UseTurbo: lda #$a6 184 | sta Irq5_TurboCheck 185 | lda #RedirectIrq 195 | sta $0315 196 | lda #Irq1 199 | sta $ffff 200 | lda #IRQ1_LINE ;Line where next IRQ happens 201 | sta $d012 202 | lda #$00 203 | sta $dc0e ;Stop CIA1 timer A 204 | lda #$81 205 | sta $dc0d ;But enable timer IRQ from it 206 | lda #$01 ;Enable raster IRQs 207 | sta $d01a 208 | lda $dc0d ;Acknowledge any pending IRQs at this point 209 | dec $d019 210 | cli 211 | 212 | ; Initialization done, return to mainloop 213 | 214 | rts 215 | 216 | ; Silence SID, blank screen & and stop raster IRQs. Used when beginning fallback mode loading 217 | 218 | stopIrqCode: 219 | jsr WaitBottom 220 | jsr SilenceSID 221 | sta $d01a ;Raster IRQs off 222 | sta $d011 ;Blank screen completely 223 | rts 224 | stopIrqCodeEnd: 225 | 226 | ; Data 227 | 228 | panelCharData: incbin bg\scorescr.chr 229 | 230 | -------------------------------------------------------------------------------- /input.s: -------------------------------------------------------------------------------- 1 | JOY_UP = $01 2 | JOY_DOWN = $02 3 | JOY_LEFT = $04 4 | JOY_RIGHT = $08 5 | JOY_FIRE = $10 6 | JOY_JUMP = $20 7 | JOY_NOJUMP = $1f 8 | 9 | KEY_DEL = 0 10 | KEY_RETURN = 1 11 | KEY_CURSORLR = 2 12 | KEY_F7 = 3 13 | KEY_F1 = 4 14 | KEY_F3 = 5 15 | KEY_F5 = 6 16 | KEY_CURSORUD = 7 17 | KEY_3 = 8 18 | KEY_W = 9 19 | KEY_A = 10 20 | KEY_4 = 11 21 | KEY_Z = 12 22 | KEY_S = 13 23 | KEY_E = 14 24 | KEY_SHIFT1 = 15 25 | KEY_5 = 16 26 | KEY_R = 17 27 | KEY_D = 18 28 | KEY_6 = 19 29 | KEY_C = 20 30 | KEY_F = 21 31 | KEY_T = 22 32 | KEY_X = 23 33 | KEY_7 = 24 34 | KEY_Y = 25 35 | KEY_G = 26 36 | KEY_8 = 27 37 | KEY_B = 28 38 | KEY_H = 29 39 | KEY_U = 30 40 | KEY_V = 31 41 | KEY_9 = 32 42 | KEY_I = 33 43 | KEY_J = 34 44 | KEY_0 = 35 45 | KEY_M = 36 46 | KEY_K = 37 47 | KEY_O = 38 48 | KEY_N = 39 49 | KEY_PLUS = 40 50 | KEY_P = 41 51 | KEY_L = 42 52 | KEY_MINUS = 43 53 | KEY_PERIOD = 44 54 | KEY_COLON = 45 55 | KEY_AT = 46 56 | KEY_COMMA = 47 57 | KEY_POUND = 48 58 | KEY_ASTERISK = 49 59 | KEY_SEMICOLON = 50 60 | KEY_HOME = 51 61 | KEY_SHIFT2 = 52 62 | KEY_EQUALS = 53 63 | KEY_ARROWU = 54 64 | KEY_SLASH = 55 65 | KEY_1 = 56 66 | KEY_ARROWL = 57 67 | KEY_CTRL = 58 68 | KEY_2 = 59 69 | KEY_SPACE = 60 70 | KEY_CBM = 61 71 | KEY_Q = 62 72 | KEY_RUNSTOP = 63 73 | KEY_NONE = $ff 74 | 75 | InitTwoButtons: 76 | 77 | ; Read joystick + scan the keyboard. Fall through to GetFireClick. 78 | ; 79 | ; Parameters: - 80 | ; Returns: - 81 | ; Modifies: A,X,Y,zpBitBuf 82 | 83 | GC_TwoButtons: lda $d419 ;Check for either POTX or POTY being low 84 | and $d41a 85 | GC_ButtonTwoDown: 86 | bpl GC_AddJump 87 | GC_ButtonTwoUp: bmi GC_NoJump 88 | 89 | GetControls: lda #$01 ;Make sure IRQs are on, as we must be in an interactive loop now 90 | sta $d01a ;(either game loop, or an I/O error retry prompt) 91 | lda joystick 92 | sta prevJoy 93 | lda #$ff 94 | sta keyType 95 | eor $dc00 ;Read joystick 96 | and #JOY_NOJUMP ;Remove extra bits 97 | sta joystick 98 | ldx twoButtonJoystick ;Check jump control (one or two button) 99 | bne GC_TwoButtons 100 | GC_OneButton: lsr ;For one button, up = jump 101 | bcc GC_NoJump 102 | GC_AddJump: lda joystick 103 | ora #JOY_JUMP 104 | sta joystick 105 | GC_NoJump: lda #$00 ;Short-circuit read of all lines to check whether there are 106 | sta $dc00 ;keys down; no need to read them one-by-one otherwise 107 | lda $dc01 108 | cmp #$ff 109 | beq GC_NoKey 110 | ldy #$07 111 | GC_RowLoop: lda reverseBitTbl,y 112 | sta $dc00 113 | lda $dc01 114 | cmp #$ff 115 | bne GC_RowFound 116 | GC_RowEmpty: dey 117 | bpl GC_RowLoop 118 | bmi GC_NoKey 119 | GC_RowFound: tax 120 | tya 121 | asl 122 | asl 123 | asl 124 | sta zpBitBuf 125 | txa 126 | ldy #$07 127 | GC_ColLoop: asl 128 | bcc GC_KeyFound 129 | dey 130 | bpl GC_ColLoop 131 | GC_KeyFound: tya 132 | ora zpBitBuf 133 | GC_KeyPress: cmp #$00 134 | beq GC_SameKey 135 | sta keyType 136 | GC_SameKey: 137 | GC_NoKey: sta GC_KeyPress+1 138 | lda #$ff-$40 ;Select reading the port 2 paddles for next frame 139 | sta $dc00 140 | 141 | ; Return whether fire has been pressed down (not held down) 142 | ; 143 | ; Parameters: - 144 | ; Returns: C=1 pressed C=0 not pressed, Z=1 if only fire pressed 145 | ; Modifies: A 146 | 147 | GetFireClick: clc 148 | lda prevJoy 149 | and #JOY_FIRE 150 | bne GFC_Not 151 | lda joystick 152 | and #JOY_NOJUMP 153 | adc #$100-JOY_FIRE ;C=1 if fire pressed 154 | GFC_Not: rts -------------------------------------------------------------------------------- /kernal.s: -------------------------------------------------------------------------------- 1 | ;Kernal zeropage variables 2 | 3 | status = $90 4 | messages = $9d 5 | fa = $ba 6 | 7 | ;BASIC vectors 8 | 9 | ierror = $0300 10 | imain = $0302 11 | 12 | ;Kernal routines 13 | 14 | ScnKey = $ff9f 15 | CIOut = $ffa8 16 | Listen = $ffb1 17 | Second = $ff93 18 | UnLsn = $ffae 19 | Talk = $ffb4 20 | Tksa = $ff96 21 | UnTlk = $ffab 22 | ACPtr = $ffa5 23 | ChkIn = $ffc6 24 | ChkOut = $ffc9 25 | ChrIn = $ffcf 26 | ChrOut = $ffd2 27 | Close = $ffc3 28 | ClAll = $ffe7 29 | Open = $ffc0 30 | SetMsg = $ff90 31 | SetNam = $ffbd 32 | SetLFS = $ffba 33 | ClrChn = $ffcc 34 | GetIn = $ffe4 35 | Load = $ffd5 36 | Save = $ffd8 37 | -------------------------------------------------------------------------------- /ldepack.s: -------------------------------------------------------------------------------- 1 | ; Exomizer + loader stored as packed data 2 | 3 | include memory.s 4 | include kernal.s 5 | 6 | org exomizerCodeStart 7 | 8 | include exomizer.s 9 | 10 | exomizerCodeEnd: 11 | 12 | OpenFile = exomizerCodeEnd 13 | SaveFile = exomizerCodeEnd+3 14 | GetByte = exomizerCodeEnd+6 15 | 16 | php 17 | jsr ChrIn 18 | plp 19 | rts 20 | jmp OpenFile 21 | 22 | ldepackCodeEnd: 23 | incbin loader.pak 24 | 25 | -------------------------------------------------------------------------------- /ldepacksym.txt: -------------------------------------------------------------------------------- 1 | Depack 2 | DepackDestSet 3 | exomizerCodeStart 4 | exomizerCodeEnd 5 | ldepackCodeEnd 6 | -------------------------------------------------------------------------------- /loadsym.txt: -------------------------------------------------------------------------------- 1 | OpenFile 2 | SaveFile 3 | GetByte 4 | InitLoader 5 | DrvMain 6 | FL_SetSpriteRangeJsr 7 | FL_MinSprY 8 | FL_MaxSprY 9 | EL_SetSpriteRangeJsr 10 | EL_MinSprY 11 | EL_MaxSprY 12 | loaderCodeStart 13 | loaderCodeEnd 14 | LOAD_KERNAL 15 | LOAD_FAKEFAST 16 | LOAD_EASYFLASH 17 | LOAD_GMOD2 18 | LOAD_FAST 19 | -------------------------------------------------------------------------------- /macros.s: -------------------------------------------------------------------------------- 1 | processor 6502 2 | 3 | mac varbase 4 | NEXT_VAR set {1} 5 | endm 6 | 7 | mac var 8 | {1} = NEXT_VAR 9 | NEXT_VAR set NEXT_VAR + 1 10 | endm 11 | 12 | mac varrange 13 | {1} = NEXT_VAR 14 | NEXT_VAR set NEXT_VAR + {2} 15 | endm 16 | 17 | mac checkvarbase 18 | if NEXT_VAR > {1} 19 | err 20 | endif 21 | endm 22 | 23 | mac definescript 24 | NEXT_EP set {1}*$100 25 | endm 26 | 27 | mac defineep 28 | EP_{1} = NEXT_EP 29 | NEXT_EP set NEXT_EP + 1 30 | endm 31 | 32 | ; Text jump. Game texts need to be located between $0000-$7fff to use 33 | 34 | mac textjump 35 | dc.b >{1} | $80 36 | dc.b <{1} 37 | endm 38 | 39 | ; BIT instruction for skipping the next 1- or 2-byte instruction 40 | 41 | mac skip1 42 | dc.b $24 43 | endm 44 | 45 | mac skip2 46 | dc.b $2c 47 | endm 48 | 49 | ; Encode 4 instruction lengths into one byte 50 | 51 | mac instrlen 52 | dc.b {1} | ({2} * 4) | ({3} * 16) | ({4} * 64) 53 | endm 54 | 55 | ; Screen redraw macros 56 | 57 | mac drawbottomedge 58 | subroutine dbe 59 | ldy $1000,x 60 | lda blkColors,y 61 | bne .1 62 | lda (dsBottomPtrLo),y 63 | sta colors+{1},x 64 | bcc .3 65 | .1: sta colors+{1},x 66 | .2: lda (dsBottomPtrLo),y 67 | .3: sta screen+{1},x 68 | subroutine dbeend 69 | endm 70 | 71 | mac drawbottom 72 | subroutine db 73 | ldy $1000,x 74 | lda blkColors,y 75 | bmi .1 76 | bne .2 77 | lda blkBL,y 78 | sta colors+{1},x 79 | sta screen+{1},x 80 | lda blkBR,y 81 | sta colors+{1}+1,x 82 | bcc .3 83 | .1: sta colors+{1},x 84 | sta colors+{1}+1,x 85 | .2: lda blkBL,y 86 | sta screen+{1},x 87 | lda blkBR,y 88 | .3: sta screen+{1}+1,x 89 | subroutine dbend 90 | endm 91 | 92 | mac drawtopedge 93 | subroutine dte 94 | ldy $1000,x 95 | lda blkColors,y 96 | bne .1 97 | lda (dsTopPtrLo),y 98 | sta colors+{1},x 99 | bcc .3 100 | .1: sta colors+{1},x 101 | .2: lda (dsTopPtrLo),y 102 | .3: sta screen+{1},x 103 | subroutine dteend 104 | endm 105 | 106 | mac drawtop 107 | subroutine dt 108 | ldy $1000,x 109 | lda blkColors,y 110 | bmi .1 111 | bne .2 112 | lda blkTL,y 113 | sta colors+{1},x 114 | sta screen+{1},x 115 | lda blkTR,y 116 | sta colors+{1}+1,x 117 | bcc .3 118 | .1: sta colors+{1},x 119 | sta colors+{1}+1,x 120 | .2: lda blkTL,y 121 | sta screen+{1},x 122 | lda blkTR,y 123 | .3: sta screen+{1}+1,x 124 | subroutine dtend 125 | endm 126 | 127 | mac drawedge 128 | subroutine de 129 | ldy $1000,x 130 | lda blkColors,y 131 | bmi .1 132 | bne .2 133 | lda (dsTopPtrLo),y 134 | sta colors+{1},x 135 | sta screen+{1},x 136 | lda (dsBottomPtrLo),y 137 | sta colors+{1}+40,x 138 | bcc .3 139 | .1: sta colors+{1},x 140 | sta colors+{1}+40,x 141 | .2: lda (dsTopPtrLo),y 142 | sta screen+{1},x 143 | lda (dsBottomPtrLo),y 144 | .3: sta screen+{1}+40,x 145 | subroutine deend 146 | endm 147 | 148 | mac drawfullblock 149 | subroutine dfb 150 | ldy $1000,x 151 | lda blkColors,y 152 | bmi .1 153 | bne .2 154 | lda blkTL,y 155 | sta colors+{1},x 156 | sta screen+{1},x 157 | lda blkTR,y 158 | sta colors+{1}+1,x 159 | sta screen+{1}+1,x 160 | lda blkBL,y 161 | sta colors+{1}+40,x 162 | sta screen+{1}+40,x 163 | lda blkBR,y 164 | sta colors+{1}+41,x 165 | bcc .3 166 | .1: sta colors+{1},x 167 | sta colors+{1}+1,x 168 | sta colors+{1}+40,x 169 | sta colors+{1}+41,x 170 | .2: lda blkTL,y 171 | sta screen+{1},x 172 | lda blkTR,y 173 | sta screen+{1}+1,x 174 | lda blkBL,y 175 | sta screen+{1}+40,x 176 | lda blkBR,y 177 | .3: sta screen+{1}+41,x 178 | subroutine dfbend 179 | endm 180 | 181 | mac drawfullblockexit 182 | subroutine dfbe 183 | ldy $1000,x 184 | lda blkColors,y 185 | bmi .1 186 | bne .2 187 | lda blkTL,y 188 | sta colors+{1},x 189 | sta screen+{1},x 190 | lda blkTR,y 191 | sta colors+{1}+1,x 192 | sta screen+{1}+1,x 193 | lda blkBL,y 194 | sta colors+{1}+40,x 195 | sta screen+{1}+40,x 196 | lda blkBR,y 197 | sta colors+{1}+41,x 198 | sta screen+{1}+41,x 199 | bcc {2} 200 | .1: sta colors+{1},x 201 | sta colors+{1}+1,x 202 | sta colors+{1}+40,x 203 | sta colors+{1}+41,x 204 | .2: lda blkTL,y 205 | sta screen+{1},x 206 | lda blkTR,y 207 | sta screen+{1}+1,x 208 | lda blkBL,y 209 | sta screen+{1}+40,x 210 | lda blkBR,y 211 | sta screen+{1}+41,x 212 | bcc {2} 213 | subroutine dfbeend 214 | endm 215 | 216 | mac loadrow 217 | txa 218 | adc mapTblLo+{3},y 219 | sta {1}+1 220 | sta {2}+1 221 | lda zpSrcHi 222 | adc mapTblHi+{3},y 223 | sta {1}+2 224 | sta {2}+2 225 | endm 226 | 227 | mac adjustedge 228 | subroutine ae 229 | inc {1}+1 230 | bne .1 231 | inc {1}+2 232 | .1: 233 | subroutine aeend 234 | endm 235 | 236 | mac copycrtcode 237 | subroutine ccc 238 | ldx #>({2}-{1}+$ff) 239 | ldy #$00 240 | lda #<{1} 241 | sta zpSrcLo 242 | lda #>{1} 243 | sta zpSrcHi 244 | lda #<{3} 245 | sta zpDestLo 246 | lda #>{3} 247 | sta zpDestHi 248 | .1: lda (zpSrcLo),y 249 | sta (zpDestLo),y 250 | iny 251 | bne .1 252 | inc zpSrcHi 253 | inc zpDestHi 254 | dex 255 | bne .1 256 | subroutine cccend 257 | endm -------------------------------------------------------------------------------- /main.s: -------------------------------------------------------------------------------- 1 | ; Rasterline debug 2 | 3 | SHOW_PLAYROUTINE_TIME = 0 4 | SHOW_CHARSETANIM_TIME = 0 5 | SHOW_SPRITEIRQ_TIME = 0 6 | SHOW_SCROLLWORK_TIME = 0 7 | SHOW_SKIPPED_FRAME = 0 8 | SHOW_FREE_TIME = 0 9 | SHOW_DEBUG_VARS = 0 10 | 11 | ; Filename and resource chunk defines 12 | 13 | F_MUSIC = $01 14 | F_CHARSET = $02 15 | F_LEVEL = $03 16 | F_CHUNK = $04-1 17 | 18 | C_COMMON = 1 ;Common sprites 19 | C_PLAYER = 2 ;Player sprites 20 | C_ENEMY = 3 ;Enemy sprites 21 | C_SCRIPT0 = 4 ;First script (loadable code) file, with player + enemy movement / render code 22 | 23 | C_FIRSTPURGEABLE = C_PLAYER ;First chunk that can be removed from memory. Put e.g. always resident spritefiles 24 | ;to lower indices 25 | C_FIRSTSCRIPT = C_SCRIPT0 ;Remember to update this, otherwise sprite etc. resources will be relocated as code! 26 | 27 | include memory.s 28 | include loadsym.s 29 | include ldepacksym.s 30 | 31 | org loaderCodeEnd 32 | 33 | EntryPoint: ldx #$ff ;Init stack pointer to top 34 | txs 35 | jsr InitAll ;Call to disposable init code 36 | 37 | lda #5 ;Adjust text margin for the health display 38 | sta textLeftMargin 39 | 40 | lda #1 41 | jsr PlaySong ;Play music. Note: some music (even a silence tune) 42 | ;needs to be initialized to get sound effect playback 43 | ;Also, loading music trashes the zone scrolling buffer, 44 | ;so must load music before changing the zone / beginning gameplay 45 | 46 | lda #0 ;Setup level / zone we're in 47 | jsr ChangeLevel 48 | lda #0 49 | jsr ChangeZone 50 | ldx #ACTI_PLAYER ;Create player actor. Player movement code is in script00.s 51 | lda #ACT_PLAYER ;to demonstrate runtime code loading / relocation 52 | sta actT,x 53 | lda #28 54 | sta actXH,x 55 | lda #$40 56 | sta actXL,x 57 | lda #15 58 | sta actYH,x 59 | lda #$00 60 | sta actD,x 61 | jsr InitActor ;Init health & actor flags 62 | jsr CenterPlayer ;Center scrolling on player & redraw 63 | jsr SavePlayerState ;Make an "in-memory checkpoint" for restarting 64 | jsr UpdateFrame ;Show screen just to demonstrate loading while screen is on 65 | jsr RedrawHUD 66 | 67 | ldy #C_COMMON 68 | jsr LoadResource ;Preload the common sprites 69 | 70 | MainLoop: jsr ScrollLogic 71 | jsr DrawActors 72 | jsr UpdateFrame 73 | jsr GetControls 74 | jsr ScrollLogic 75 | jsr UpdateActors 76 | jsr UpdateFrame 77 | jsr UpdateLevelObjects 78 | jsr RedrawHUD 79 | jsr CheckRestart 80 | jmp MainLoop 81 | 82 | RedrawHUD: lda actHp+ACTI_PLAYER ;Redraw health to left side of scorepanel if changed 83 | cmp displayedHealth 84 | beq RH_SameHealth 85 | sta displayedHealth 86 | jsr ConvertToBCD8 87 | ldx #0 88 | lda #94 ;Health symbol 89 | jsr PrintPanelChar 90 | jsr Print3BCDDigits ;Health value 91 | RH_SameHealth: lda ammo ;Redraw ammo to right side of scorepanel if changed 92 | cmp displayedAmmo 93 | beq RH_SameAmmo 94 | sta displayedAmmo 95 | jsr ConvertToBCD8 96 | ldx #34 97 | lda #95 ;Ammo symbol 98 | jsr PrintPanelChar 99 | jsr Print3BCDDigits ;Ammo value 100 | RH_SameAmmo: rts 101 | 102 | CheckRestart: lda actT+ACTI_PLAYER ;Check if player actor vanished (destroyed) 103 | bne CR_NoRestart 104 | sta scrollSX ;Stop scrolling 105 | sta scrollSY 106 | dec restartDelay ;Two second delay (50 mainloops or 100 frames) 107 | bne CR_NoRestart 108 | lda #50 109 | sta restartDelay 110 | jsr RestoreCheckpoint ;Restore player & world state from last entered area & start again 111 | lda actHp+ACTI_PLAYER 112 | cmp #50 ;Ensure at least half health after restart 113 | bcs CR_HealthOK 114 | lda #50 115 | sta actHp+ACTI_PLAYER 116 | CR_HealthOK: 117 | CR_NoRestart: rts 118 | 119 | Print3BCDDigits:lda zpDestHi 120 | jsr PrintBCDDigit 121 | lda zpDestLo 122 | jmp PrintBCDDigits 123 | 124 | displayedHealth:dc.b $ff 125 | displayedAmmo: dc.b $ff 126 | restartDelay: dc.b 50 127 | 128 | randomAreaStart: 129 | 130 | include raster.s ;Include rest of the engine code 131 | include sound.s 132 | include input.s 133 | include screen.s 134 | include sprite.s 135 | include math.s 136 | include file.s 137 | include panel.s 138 | include actor.s 139 | include physics.s 140 | include ai.s 141 | include level.s 142 | 143 | randomAreaEnd: 144 | 145 | include playroutinedata.s ;Include datas 146 | include sounddata.s 147 | include actordata.s 148 | include miscdata.s 149 | include aligneddata.s 150 | 151 | ; Dynamic allocation area begin 152 | 153 | fileAreaStart: 154 | include init.s ;Disposable init code -------------------------------------------------------------------------------- /math.s: -------------------------------------------------------------------------------- 1 | ; Add a 8-bit value to a 16-bit value 2 | ; 3 | ; Parameters: A value to be added, X zeropage base 4 | ; Returns: zeropage result 5 | ; Modifies: A 6 | 7 | GetNext2MapRows:jsr AddMapSizeX 8 | AddMapSizeX: lda mapSizeX 9 | Add8: clc 10 | adc $00,x 11 | sta $00,x 12 | bcc Add8_Skip 13 | inc $01,x 14 | Add8_Skip: rts 15 | 16 | ; Add two 16-bit values 17 | ; 18 | ; Parameters: X destination zeropage base, Y source zeropage base 19 | ; Returns: zeropage result 20 | ; Modifies: A 21 | 22 | Add16: lda $00,x 23 | clc 24 | adc $00,y 25 | sta $00,x 26 | lda $01,x 27 | adc $01,y 28 | sta $01,x 29 | rts 30 | 31 | ; Multiply two unsigned 8-bit values 32 | ; 33 | ; Parameters: A,Y values to be multiplied, X destination zeropage base 34 | ; Returns: zeropage 16-bit result, A highbyte of result 35 | ; Modifies: A,Y 36 | 37 | MulU: sta $00,x 38 | tya 39 | beq MulU_Zero 40 | dey 41 | sty $01,x 42 | ldy #$07 43 | lda #$00 44 | lsr $00,x 45 | bcc MulU_Shift1 46 | adc $01,x 47 | MulU_Shift1: ror 48 | ror $00,x 49 | bcc MulU_Shift2 50 | adc $01,x 51 | MulU_Shift2: dey 52 | bne MulU_Shift1 53 | ror 54 | sta $01,x 55 | ror $00,x 56 | rts 57 | MulU_Zero: sta $00,x 58 | sta $01,x 59 | rts 60 | 61 | ; Divide two unsigned 8-bit values 62 | ; 63 | ; Parameters: A value to be divided, Y divider, X destination zeropage base 64 | ; Returns: zeropage result, A remainder 65 | ; Modifies: A,X,Y 66 | 67 | DivU: sta $00,x 68 | tya 69 | sta $01,x 70 | lda #$00 71 | asl $00,x 72 | ldy #$07 73 | DivU_Loop: rol 74 | cmp $01,x 75 | bcc DivU_Skip 76 | sbc $01,x 77 | DivU_Skip: rol $00,x 78 | dey 79 | bpl DivU_Loop 80 | rts 81 | 82 | ; Negate and arithmetic shift right a 8-bit value 83 | ; 84 | ; Parameters: A value to be negated & shifted 85 | ; Returns: A result 86 | ; Modifies: A 87 | 88 | Negate8Asr8: eor #$ff 89 | clc 90 | adc #$01 91 | 92 | ; Arithmetic shift right a 8-bit value 93 | ; 94 | ; Parameters: A value to be shifted 95 | ; Returns: A result 96 | ; Modifies: A 97 | 98 | Asr8: cmp #$80 99 | ror 100 | bpl Asr8Pos 101 | adc #$00 102 | Asr8Pos: rts 103 | 104 | ; Return a 8bit pseudorandom number 105 | ; 106 | ; Parameters: - 107 | ; Returns: A number ($00-$ff) 108 | ; Modifies: A 109 | 110 | Random: inc RandomAdd+1 111 | bne RandomSeed 112 | lda RandomAdd+2 113 | cmp #>randomAreaEnd-1 114 | bcc RandomOK 115 | lda #>randomAreaStart-2 116 | RandomOK: adc #$01 117 | sta RandomAdd+2 118 | RandomSeed: lda #$00 119 | asl 120 | RandomAdd: adc randomAreaStart 121 | sta RandomSeed+1 122 | rts 123 | 124 | ; Turn a number into a byte offset into a bit-table and a bitmask 125 | ; 126 | ; Parameters: A number, zpSrcLo base offset (DecodeBitsOfs) 127 | ; Returns: A bitmask, Y byte offset, C=0 128 | ; Modifies: A,Y,zpSrcLo 129 | 130 | DecodeBit: ldy #$00 131 | sty zpSrcLo 132 | DecodeBitOfs: pha 133 | and #$07 134 | tay 135 | lda bitTbl,y 136 | sta DB_Value+1 137 | pla 138 | lsr 139 | lsr 140 | lsr 141 | clc 142 | adc zpSrcLo 143 | tay 144 | DB_Value: lda #$00 145 | rts 146 | -------------------------------------------------------------------------------- /memory.s: -------------------------------------------------------------------------------- 1 | include defines.s 2 | include macros.s 3 | 4 | ; Zeropage variables 5 | 6 | varbase $02 7 | 8 | var loadBufferPos ;Loader variables. Note: order is important, used for selfmod optimization code 9 | var loadTempReg 10 | var fileOpen 11 | var ntscFlag 12 | var loaderMode 13 | var fileNumber ;Not needed by loader, but used by main code to remember the file currently accessed 14 | 15 | var zpLenLo ;Exomizer 3 depackroutine variables 16 | var zpSrcLo 17 | var zpSrcHi 18 | var zpDestLo 19 | var zpDestHi 20 | var zpBitsLo 21 | var zpBitsHi 22 | var zpBitBuf 23 | 24 | zpLenHi = zpBitsLo ;Exomizer 3 doesn't use zpBitsLo, but the engine uses it as an extra pointer / counter 25 | 26 | var xLo ;Actor render / spawn coordinates 27 | var yLo 28 | var xHi 29 | var yHi 30 | 31 | var cacheFrame ;Sprite render variables 32 | var sprFrameNum 33 | var numSpr 34 | var numBounds 35 | var actColorAnd 36 | var actColorOr 37 | var actYMSB 38 | 39 | var actIndex ;Actor variables 40 | var actLo 41 | var actHi 42 | var currFlags 43 | var wpnLo 44 | var wpnHi 45 | var wpnFlags 46 | 47 | var loadRes ;Current resource file for load 48 | var freeMemLo ;Memory allocator variables 49 | var freeMemHi 50 | var musicDataLo 51 | var musicDataHi 52 | var zoneBufferLo 53 | var zoneBufferHi 54 | 55 | var nextLvlActIndex ;Misc. game vars 56 | 57 | varrange actXH,MAX_ACT ;Actor ZP variables 58 | varrange actYH,MAX_ACT 59 | varrange actSX,MAX_ACT 60 | varrange actSY,MAX_ACT 61 | varrange actF1,MAX_ACT 62 | 63 | checkvarbase $90 64 | 65 | varbase $a6 66 | 67 | var joystick ;Input variables 68 | var prevJoy 69 | var keyType 70 | 71 | var levelNum ;Zone / level variables 72 | var zoneNum 73 | var mapSizeX 74 | var mapSizeY 75 | var zoneBg1 76 | var zoneBg2 77 | var zoneBg3 78 | var lastNavArea 79 | 80 | var animObj ;Levelobject variables. First 3 also used in zone init 81 | var animObjFrame 82 | var animObjTarget 83 | var usableObj 84 | var autoDeactObj 85 | var atObj 86 | 87 | checkvarbase $b7 88 | 89 | varbase $c0 90 | 91 | varrange sprOrder,MAX_SPR+1 92 | 93 | var scrollX ;Scrolling variables 94 | var scrollY 95 | var scrollSX 96 | var scrollSY 97 | var scrCounter 98 | var blockX 99 | var blockY 100 | var mapX 101 | var mapY 102 | 103 | var textTime ;Text printing variables 104 | var textLeftMargin 105 | var textRightMargin 106 | var textLo 107 | var textHi 108 | 109 | var irqSaveA ;IRQ variables 110 | var irqSaveX 111 | var irqSaveY 112 | var frameNumber 113 | var firstSortSpr 114 | var newFrameFlag 115 | var drawScreenFlag 116 | var dsBlockX 117 | var dsBlockY 118 | var dsStartX 119 | var dsEdgeX 120 | var dsTopPtrLo 121 | var dsTopPtrHi 122 | var dsBottomPtrLo 123 | var dsBottomPtrHi 124 | 125 | var pattPtrLo ;Playroutine 126 | var pattPtrHi 127 | var trackPtrLo 128 | var trackPtrHi 129 | var masterVol 130 | var sfxTemp 131 | 132 | checkvarbase $100 133 | 134 | textCursor = loadBufferPos ;Reused during text printing (should never load mid-line!) 135 | 136 | dataSizeLo = xHi ;Reused during resource load 137 | dataSizeHi = yHi 138 | 139 | zoneCharset = animObj ;Reused during zone init 140 | zoneDataOffsetLo = animObjFrame 141 | zoneDataOffsetHi = animObjTarget 142 | 143 | complexSprCount = xHi ;Reused during actor render 144 | complexSprTemp = yHi 145 | oldSprLo = wpnLo 146 | oldSprHi = wpnHi 147 | oldSprHeaderLo = loadBufferPos 148 | oldSprHeaderHi = loadTempReg 149 | cacheAdr = wpnLo 150 | sliceMask = wpnHi 151 | 152 | currFireCtrl = xLo ;Reused during actor move / attack 153 | currCtrl = yLo 154 | edgeCtrl = xHi 155 | moveSpeed = yHi 156 | sideOffset = zpBitsLo 157 | topOffset = zpBitsHi 158 | slopeX = zpBitBuf 159 | saveActIndex = actColorAnd 160 | saveHp = actColorOr 161 | 162 | blockCtrl = xHi ;Reused during attack 163 | aimDir = zpBitsLo 164 | bulletDir = zpBitsHi 165 | wpnFlagsDisp = loadBufferPos 166 | 167 | bounceBrake = yLo ;Reused during bounce physics 168 | bouncePrevX = xHi 169 | bouncePrevY = yHi 170 | 171 | signXDist = xLo ;Reused during AI 172 | absXDist = xHi 173 | signYDist = yLo 174 | absYDist = yHi 175 | targetX = zpSrcLo 176 | targetY = zpSrcHi 177 | srcNavArea = zpDestLo 178 | currentDist = zpDestHi 179 | bestDist = zpBitsLo 180 | bestArea = zpBitsHi 181 | aggression = zpLenLo 182 | 183 | bboxTop = zpBitsLo ;AI firing dir check 184 | bboxBottom = zpBitsHi 185 | wpnHeight = zpBitBuf 186 | 187 | lineX = xLo ;Reused during linecheck 188 | lineY = yLo 189 | lineYCopy = xHi 190 | lineSlope = yHi 191 | lineCount = zpBitsLo 192 | 193 | aoEndFrame = xLo ;Object animation 194 | aoTemp = yLo 195 | 196 | promptIndex = xLo ;Interaction prompts 197 | promptType = yLo 198 | 199 | ; Memory areas and non-zeropage variables 200 | 201 | depackBuffer = $0100 202 | loadBuffer = $0200 203 | StopIrq = $02a7 ;Kernal load/save preparation: disable IRQs / blank screen if necessary 204 | 205 | exomizerCodeStart = $0334 206 | 207 | scriptCodeRelocStart = $8000 208 | videoBank = $c000 209 | fileAreaEnd = $d000 210 | spriteCache = $d000 211 | colors = $d800 212 | panelScreen = $e000 213 | panelChars = $e000 214 | blkTL = $e400 215 | blkTR = $e500 216 | blkBL = $e600 217 | blkBR = $e700 218 | chars = $e800 219 | blkInfo = $f000 220 | blkColors = $f100 221 | lvlObjAnimFrames = $f200 222 | charAnimCodeJump = $f2bd 223 | miscVarArea1 = $f2c0 224 | screen = $f800 225 | emptySprite = $fc00 226 | miscVarArea2 = $fc40 227 | 228 | varbase panelScreen+24*40-1 229 | varrange sprY,MAX_SPR+1 230 | varrange boundsAct,MAX_BOUNDS 231 | checkvarbase panelScreen+1016 232 | 233 | varbase screen+SCROLLROWS*40 234 | varrange sprX,MAX_SPR 235 | varrange sprF,MAX_SPR 236 | varrange sprC,MAX_SPR 237 | varrange sprAct,MAX_SPR 238 | checkvarbase screen+1016 239 | 240 | varbase miscVarArea1 241 | 242 | ; Level objects 243 | 244 | varrange lvlObjX,MAX_LVLOBJ 245 | varrange lvlObjY,MAX_LVLOBJ 246 | varrange lvlObjZ,MAX_LVLOBJ 247 | varrange lvlObjFlags,MAX_LVLOBJ 248 | varrange lvlObjSize,MAX_LVLOBJ 249 | varrange lvlObjFrame,MAX_LVLOBJ 250 | varrange lvlObjDL,MAX_LVLOBJ 251 | varrange lvlObjDH,MAX_LVLOBJ 252 | 253 | ; Leveldata actors 254 | 255 | varrange lvlActX,MAX_LVLACT 256 | varrange lvlActY,MAX_LVLACT 257 | varrange lvlActZ,MAX_LVLACT 258 | varrange lvlActT,MAX_LVLACT 259 | varrange lvlActWpn,MAX_LVLACT 260 | varrange lvlActOrg,MAX_LVLACT 261 | 262 | varbase miscVarArea2 263 | 264 | ; Sprite caching & resources 265 | 266 | varrange fileNumObjects,MAX_CHUNKFILES 267 | varrange cacheSprAge,MAX_CACHESPRITES 268 | varrange cacheSprFrame,MAX_CACHESPRITES 269 | varrange cacheSprFile,MAX_CACHESPRITES 270 | varrange fileLo,MAX_CHUNKFILES 271 | varrange fileHi,MAX_CHUNKFILES 272 | varrange fileAge,MAX_CHUNKFILES 273 | 274 | ; Actor bounds 275 | 276 | varrange boundsL,MAX_BOUNDS 277 | varrange boundsR,MAX_BOUNDS 278 | varrange boundsU,MAX_BOUNDS 279 | varrange boundsD,MAX_BOUNDS 280 | 281 | ; Navareas 282 | 283 | varrange navAreaType,MAX_NAVAREAS 284 | varrange navAreaL,MAX_NAVAREAS 285 | varrange navAreaR,MAX_NAVAREAS 286 | varrange navAreaU,MAX_NAVAREAS 287 | varrange navAreaD,MAX_NAVAREAS 288 | 289 | ; Maprowtable 290 | 291 | varrange mapTblLo,MAX_MAPROWS 292 | varrange mapTblHi,MAX_MAPROWS 293 | 294 | checkvarbase $fffa -------------------------------------------------------------------------------- /miscdata.s: -------------------------------------------------------------------------------- 1 | saveMiscVarLo: dc.b actT 10 | dc.b >actXH 11 | dc.b >actYH 12 | dc.b >actD 13 | dc.b >actHp 14 | dc.b >levelNum 15 | dc.b >zoneNum 16 | 17 | NUM_SAVEMISCVARS = saveMiscVarHi - saveMiscVarLo 18 | -------------------------------------------------------------------------------- /music/example.sng: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cadaver/c64gameframework/15eaa821599c860ab94009085d6b340f93f65670/music/example.sng -------------------------------------------------------------------------------- /panel.s: -------------------------------------------------------------------------------- 1 | INDEFINITE_TEXT_DURATION = $7f 2 | 3 | ; Redraw requested scorepanel items + advance text printing as necessary 4 | ; 5 | ; Parameters: - 6 | ; Returns: - 7 | ; Modifies: A,X,Y,loader temp vars 8 | 9 | UpdatePanel: lda textTime 10 | beq UP_TextDone 11 | cmp #INDEFINITE_TEXT_DURATION*2 12 | bcs UP_TextDone 13 | dec textTime 14 | beq UpdateText 15 | UP_TextDone: rts 16 | 17 | ; Print continued panel text. Should be called immediately after printing the beginning part. 18 | ; 19 | ; Parameters: A,X text address 20 | ; Returns: - 21 | ; Modifies: A,X,Y,zpSrcLo,zpSrcHi,text variables 22 | 23 | ContinuePanelText: 24 | sta textLo 25 | stx textHi 26 | ldx textCursor 27 | bpl UT_ContinueText 28 | 29 | ; Clear the panel text 30 | ; 31 | ; Parameters: - 32 | ; Returns: C=1 33 | ; Modifies: A,X,Y,zpSrcLo,zpSrcHi,text variables 34 | 35 | ClearPanelText: ldx #$00 36 | ldy #$00 37 | skip2 38 | 39 | ; Print text to panel, possibly multi-line 40 | ; 41 | ; Parameters: A,X text address, Y delay in game logic frames (25 = 1 sec) 42 | ; Returns: - 43 | ; Modifies: A,X,Y,zpSrcLo,zpSrcHi,text variables 44 | 45 | PrintPanelTextIndefinite: 46 | ldy #INDEFINITE_TEXT_DURATION 47 | PrintPanelText: sty UT_TextDelay+1 48 | sta textLo 49 | stx textHi 50 | UpdateText: ldx textLeftMargin 51 | UT_ContinueText:ldy #$00 52 | lda textHi 53 | beq UT_NoLine 54 | lda (textLo),y 55 | bne UT_BeginLine 56 | UT_NoLine: sta textTime 57 | sta textHi 58 | ldx textLeftMargin 59 | bpl UT_ClearEndOfLine 60 | UT_BeginLine: 61 | UT_TextDelay: lda #$00 62 | asl 63 | sta textTime 64 | UT_PrintTextLoop: 65 | sty zpSrcHi 66 | stx zpSrcLo 67 | UT_ScanWordLoop:lda (textLo),y 68 | beq UT_ScanWordDone 69 | bmi UT_ScanWordDone 70 | cmp #$20 71 | beq UT_ScanWordDone 72 | cmp #"-" 73 | beq UT_ScanWordDone2 74 | inc zpSrcLo 75 | iny 76 | bne UT_ScanWordLoop 77 | UT_ScanWordDone2: 78 | inc zpSrcLo 79 | UT_ScanWordDone:ldy zpSrcHi 80 | lda textRightMargin 81 | cmp zpSrcLo 82 | bcs UT_WordCmp 83 | UT_EndLine: stx textCursor 84 | tya 85 | ldx #textLo 86 | jsr Add8 87 | ldx textCursor 88 | UT_ClearEndOfLine: 89 | jmp PrintSpaceUntilRightMargin 90 | UT_WordLoop: lda (textLo),y 91 | jsr PrintPanelChar 92 | iny 93 | UT_WordCmp: cpx zpSrcLo 94 | bcc UT_WordLoop 95 | UT_SpaceLoop: lda (textLo),y 96 | beq UT_EndLine 97 | bmi UT_TextJump 98 | cmp #$20 99 | bne UT_SpaceLoopDone 100 | cpx textRightMargin 101 | bcs UT_SpaceSkip 102 | jsr PrintPanelChar 103 | UT_SpaceSkip: iny 104 | bne UT_SpaceLoop 105 | UT_SpaceLoopDone: 106 | cpx textRightMargin 107 | bcc UT_PrintTextLoop 108 | bcs UT_EndLine 109 | UT_TextJump: pha 110 | iny 111 | lda (textLo),y 112 | sta textLo 113 | pla 114 | and #$7f 115 | sta textHi 116 | ldy #$00 117 | beq UT_PrintTextLoop 118 | 119 | ; Print a BCD value to panel 120 | ; 121 | ; Parameters: A value, X position 122 | ; Returns: X position incremented 123 | ; Modifies: A,X 124 | 125 | Print3BCDDigitsLeftAlign: 126 | lda zpDestHi 127 | beq P3BDLA_SkipFirst 128 | jsr PrintBCDDigit 129 | PrintBCDDigits: lda zpDestLo 130 | pha 131 | lsr 132 | lsr 133 | lsr 134 | lsr 135 | bpl PBDLA_NoSkip 136 | P3BDLA_SkipFirst: 137 | lda zpDestLo 138 | PrintBCDDigitsLeftAlign: 139 | pha 140 | lsr 141 | lsr 142 | lsr 143 | lsr 144 | beq PBDLA_Skip 145 | PBDLA_NoSkip: ora #$30 146 | PBD_Common: jsr PrintPanelChar 147 | PBDLA_Skip: pla 148 | and #$0f 149 | 150 | PrintBCDDigit: ora #$30 151 | skip2 152 | PrintSpace: lda #$20 153 | PrintPanelChar: sta panelScreen+SCROLLROWS*40,x 154 | lda #$01 155 | sta colors+SCROLLROWS*40,x 156 | inx 157 | rts 158 | 159 | PrintBCDDigitsRightAlign: 160 | pha 161 | lsr 162 | lsr 163 | lsr 164 | lsr 165 | bne PBDLA_NoSkip 166 | lda #$20 167 | bne PBD_Common 168 | 169 | ; Print spaces until a specific X-position 170 | ; 171 | ; Parameters: A end position+1 172 | ; Returns: X position incremented,C=1 173 | ; Modifies: A,X 174 | 175 | PrintSpaceUntilRightMargin: 176 | lda textRightMargin 177 | PrintSpaceUntil:sta PSU_Loop+1 178 | PSU_Loop: cpx #$00 179 | bcs PSU_Done 180 | jsr PrintSpace 181 | bne PSU_Loop 182 | PSU_Done: rts 183 | 184 | ; Convert a 8-bit value to BCD 185 | ; 186 | ; Parameters: A value 187 | ; Returns: zpDestLo-Hi BCD value 188 | ; Modifies: A,Y,zpSrcLo-Hi,zpDestLo-Hi 189 | 190 | ConvertToBCD8: sta zpSrcHi 191 | ldy #$08 192 | CTB_Common: lda #$00 193 | sta zpDestLo 194 | sta zpDestHi 195 | sed 196 | CTB_Loop: asl zpSrcLo 197 | rol zpSrcHi 198 | lda zpDestLo 199 | adc zpDestLo 200 | sta zpDestLo 201 | lda zpDestHi 202 | adc zpDestHi 203 | sta zpDestHi 204 | dey 205 | bne CTB_Loop 206 | cld 207 | rts 208 | 209 | ; Convert a 16-bit value to BCD 210 | ; 211 | ; Parameters: A,X value 212 | ; Returns: zpDestLo-Hi BCD value 213 | ; Modifies: A,Y,zpSrcLo-Hi,zpDestLo-Hi 214 | 215 | ConvertToBCD16: sta zpSrcLo 216 | stx zpSrcHi 217 | ldy #$10 218 | bne CTB_Common 219 | 220 | if SHOW_DEBUG_VARS > 0 221 | 222 | PrintHexByte: pha 223 | lsr 224 | lsr 225 | lsr 226 | lsr 227 | jsr PrintHexDigit 228 | pla 229 | and #$0f 230 | PrintHexDigit: cmp #$0a 231 | bcc PrintHexDigit_IsNumber 232 | adc #$06 233 | PrintHexDigit_IsNumber: 234 | adc #$30 235 | jmp PrintPanelChar 236 | 237 | endif 238 | 239 | ; Begin a fullscreen text display 240 | ; 241 | ; Parameters: - 242 | ; Returns: - 243 | ; Modifies: A,X,Y 244 | 245 | InitTextScreen: jsr BlankScreen 246 | ldx #$00 247 | stx Irq1_Bg1+1 248 | ITS_Loop: lda #$20 249 | sta screen,x 250 | sta screen+$100,x 251 | sta screen+$200,x 252 | sta screen+SCROLLROWS*40-$100,x 253 | inx 254 | bne ITS_Loop 255 | jsr WaitBottom 256 | lda #TEXTSCR_D018 257 | sta Irq1_D018+1 258 | rts 259 | 260 | ; Find offset of text row on the screen 261 | ; 262 | ; Parameters: X column, Y row 263 | ; Returns: xLo-yLo row offset, zpDestLo-zpDestHi screen pointer, zpBitsLo-zpBitsHi color pointer 264 | ; Modifies: A,X,Y 265 | 266 | GetRowAddress: txa 267 | pha 268 | lda #40 269 | ldx #colors 286 | sta zpBitsHi 287 | ora #>screen 288 | sta zpDestHi 289 | ldy #$00 290 | rts 291 | 292 | ; Print text script resource to screen 293 | ; 294 | ; Parameters: A,X Script entrypoint & file, xLo-yLo Row offset, PT_Color Text color 295 | ; Returns: Text pointer & row offset incremented 296 | ; Modifies: A,X,Y 297 | 298 | PrintTextResource: 299 | jsr GetScriptResource 300 | 301 | ; Print nullterminated text to screen 302 | ; 303 | ; Parameters: zpSrcLo-zpSrcHi text pointer, xLo-yLo Row offset, PT_Color+1 Text color 304 | ; Returns: Text pointer & row offset incremented 305 | ; Modifies: A,X,Y 306 | 307 | PrintText: jsr GetRowAddressFromOffset 308 | PT_Loop: lda (zpSrcLo),y 309 | beq PT_Done 310 | jsr PrintChar 311 | bne PT_Loop 312 | PT_Done: tya 313 | ldx #Play_SongTblAccess1 - >PlayRoutine + (FIXUP_NOSIZE+FIXUP_ZERO)*4 41 | dc.b >Play_SongTblAccess2 - >PlayRoutine + (FIXUP_NOSIZE+FIXUP_ZERO)*4 42 | dc.b >Play_SongTblAccess3 - >PlayRoutine + (FIXUP_NOSIZE+FIXUP_ZERO)*4 43 | dc.b >Play_PattTblLoM1Access - >PlayRoutine + (FIXUP_SONGSIZE+FIXUP_MINUS1)*4 44 | dc.b >Play_PattTblHiM1Access - >PlayRoutine + (FIXUP_PATTSIZE+FIXUP_MINUS1)*4 45 | dc.b >Play_InsADM1Access - >PlayRoutine + (FIXUP_PATTSIZE+FIXUP_MINUS1)*4 46 | dc.b >Play_InsSRM1Access - >PlayRoutine + (FIXUP_INSSIZE+FIXUP_MINUS1)*4 47 | dc.b >Play_InsFirstWaveM1Access - >PlayRoutine + (FIXUP_INSSIZE+FIXUP_MINUS1)*4 48 | dc.b >Play_InsPulsePosM1Access - >PlayRoutine + (FIXUP_INSSIZE+FIXUP_MINUS1)*4 49 | dc.b >Play_InsFiltPosM1Access - >PlayRoutine + (FIXUP_INSSIZE+FIXUP_MINUS1)*4 50 | dc.b >Play_InsWavePosM1Access - >PlayRoutine + (FIXUP_INSSIZE+FIXUP_MINUS1)*4 51 | dc.b >Play_WaveTblM1Access - >PlayRoutine + (FIXUP_LEGATOINSSIZE+FIXUP_MINUS1)*4 52 | dc.b >Play_NoteTblM1Access1 - >PlayRoutine + (FIXUP_WAVESIZE+FIXUP_MINUS1)*4 53 | dc.b >Play_NoteTblM1Access2 - >PlayRoutine + (FIXUP_NOSIZE+FIXUP_MINUS1)*4 54 | dc.b >Play_NoteTblM1Access3 - >PlayRoutine + (FIXUP_NOSIZE+FIXUP_MINUS1)*4 55 | dc.b >Play_WaveNextTblM1Access1 - >PlayRoutine + (FIXUP_WAVESIZE+FIXUP_MINUS1)*4 56 | dc.b >Play_WaveNextTblM1Access2 - >PlayRoutine + (FIXUP_NOSIZE+FIXUP_MINUS1)*4 57 | dc.b >Play_WaveNextTblM1Access3 - >PlayRoutine + (FIXUP_NOSIZE+FIXUP_MINUS1)*4 58 | dc.b >Play_WaveNextTblM1Access4 - >PlayRoutine + (FIXUP_NOSIZE+FIXUP_MINUS1)*4 59 | dc.b >Play_PulseLimitTblM1Access - >PlayRoutine + (FIXUP_WAVESIZE+FIXUP_MINUS1)*4 60 | dc.b >Play_PulseLimitTblM81Access - >PlayRoutine + (FIXUP_NOSIZE+FIXUP_MINUS81)*4 61 | dc.b >Play_PulseSpdTblM1Access - >PlayRoutine + (FIXUP_PULSESIZE+FIXUP_MINUS1)*4 62 | dc.b >Play_PulseNextTblM1Access - >PlayRoutine + (FIXUP_PULSESIZE+FIXUP_MINUS1)*4 63 | dc.b >Play_PulseNextTblM81Access - >PlayRoutine + (FIXUP_NOSIZE+FIXUP_MINUS81)*4 64 | dc.b >Play_FiltLimitTblM1Access - >PlayRoutine + (FIXUP_PULSESIZE+FIXUP_MINUS1)*4 65 | dc.b >Play_FiltLimitTblM81Access - >PlayRoutine + (FIXUP_NOSIZE+FIXUP_MINUS81)*4 66 | dc.b >Play_FiltSpdTblM1Access - >PlayRoutine + (FIXUP_FILTSIZE+FIXUP_MINUS1)*4 67 | dc.b >Play_FiltSpdTblM81Access - >PlayRoutine + (FIXUP_NOSIZE+FIXUP_MINUS81)*4 68 | dc.b >Play_FiltNextTblM1Access - >PlayRoutine + (FIXUP_FILTSIZE+FIXUP_MINUS1)*4 69 | dc.b >Play_FiltNextTblM81Access - >PlayRoutine + (FIXUP_NOSIZE+FIXUP_MINUS81)*4 70 | 71 | ; In settable music data mode, include dummy music data labels so that the player 72 | ; will not complain when assembled 73 | 74 | musicHeader: 75 | songTbl: 76 | pattTblLo: 77 | pattTblHi: 78 | insAD: 79 | insSR: 80 | insFirstWave: 81 | insWavePos: 82 | insPulsePos: 83 | insFiltPos: 84 | waveTbl: 85 | noteTbl: 86 | waveNextTbl: 87 | pulseLimitTbl: 88 | pulseSpdTbl: 89 | pulseNextTbl: 90 | filtLimitTbl: 91 | filtSpdTbl: 92 | filtNextTbl: -------------------------------------------------------------------------------- /sounddata.s: -------------------------------------------------------------------------------- 1 | SFX_NONE = 0 2 | SFX_GUN = 1 3 | SFX_PICKUP = 2 4 | SFX_EXPLOSION = 3 5 | 6 | ; Sound effect table 7 | 8 | sfxTblLo: dc.b sfxGun 13 | dc.b >sfxPickup 14 | dc.b >sfxExplosion 15 | 16 | sfxGun: dc.b SFXINIT+SFXPULSE,$00,$c8,$08 ;ADSR $00c8, pulsewidth $80 17 | dc.b SFXWAVE+SFXFREQ,$81,$c0 18 | dc.b SFXWAVE+SFXFREQ,$41,$0c 19 | dc.b SFXFREQMOD,$ff ;Decrease freq high with 1 per frame 20 | dc.b SFXWAVE,$40 21 | dc.b SFXDELAY-$0a ;Delay for 10 frames (let freqmod run) 22 | dc.b SFXEND 23 | 24 | sfxPickup: dc.b SFXINIT+SFXPULSE,$00,$d6,$07 ;ADSR $00d6, pulsewidth $70 25 | dc.b SFXWAVE+SFXFREQ,$81,$d0 26 | dc.b SFXWAVE+SFXFREQ,$41,$0c 27 | dc.b SFXWAVE+SFXFREQ,$81,$c0 28 | dc.b SFXWAVE+SFXFREQ,$40,$16 29 | dc.b SFXDELAY-$01 30 | dc.b SFXFREQ,$1d 31 | dc.b SFXDELAY-$01 32 | dc.b SFXFREQ,$16 33 | dc.b SFXEND 34 | 35 | sfxExplosion: dc.b SFXINIT+SFXPULSE,$0b,$e9,$08 ;ADSR $0be9, pulsewidth $80 36 | dc.b SFXWAVE+SFXFREQ,$81,$50 37 | dc.b SFXWAVE+SFXFREQ,$41,$0c 38 | dc.b SFXFREQ,$09 39 | dc.b SFXFREQ,$06 40 | dc.b SFXFREQ,$03 41 | dc.b SFXWAVE+SFXFREQ+SFXFREQMOD,$81,$02,$01 42 | dc.b SFXDELAY-$03 43 | dc.b SFXFREQ,$01 44 | dc.b SFXDELAY-$02 45 | dc.b SFXWAVE+SFXFREQ,$80,$00 46 | dc.b SFXDELAY-$02 47 | dc.b SFXFREQ,$01 48 | dc.b SFXDELAY-$02 49 | dc.b SFXFREQ,$02 50 | dc.b SFXDELAY-$02 51 | dc.b SFXFREQ,$01 52 | dc.b SFXDELAY-$02 53 | dc.b SFXFREQ,$00 54 | dc.b SFXDELAY-$02 55 | dc.b SFXFREQ,$01 56 | dc.b SFXDELAY-$02 57 | dc.b SFXFREQ,$00 58 | dc.b SFXDELAY-$02 59 | dc.b SFXEND 60 | -------------------------------------------------------------------------------- /spr/common.spr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cadaver/c64gameframework/15eaa821599c860ab94009085d6b340f93f65670/spr/common.spr -------------------------------------------------------------------------------- /spr/common.spr.res: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cadaver/c64gameframework/15eaa821599c860ab94009085d6b340f93f65670/spr/common.spr.res -------------------------------------------------------------------------------- /spr/enemy.spr: -------------------------------------------------------------------------------- 1 |                      -------------------------------------------------------------------------------- /spr/enemy.spr.res: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cadaver/c64gameframework/15eaa821599c860ab94009085d6b340f93f65670/spr/enemy.spr.res -------------------------------------------------------------------------------- /spr/player.spr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cadaver/c64gameframework/15eaa821599c860ab94009085d6b340f93f65670/spr/player.spr -------------------------------------------------------------------------------- /spr/player.spr.res: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cadaver/c64gameframework/15eaa821599c860ab94009085d6b340f93f65670/spr/player.spr.res -------------------------------------------------------------------------------- /spr/spredit.cfg: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /tools/Makefile: -------------------------------------------------------------------------------- 1 | all: worlded3.exe spred3.exe gt2mini.exe usecount.exe makeef.exe makegmod2.exe pack3.exe pchunk3.exe maked64.exe symbols.exe filejoin.exe filesplit.exe bmeconv.exe datafile.exe dat2inc.exe gfxconv.exe 2 | 3 | clean: 4 | del *.exe 5 | del *.spr 6 | del editor.pal 7 | del editor.dat 8 | del editdata.c 9 | 10 | editor.dat: bmeconv.exe datafile.exe editor.lbm editfont.lbm 11 | bmeconv -s -t255 -r254 -h253 editor.lbm editor.spr 12 | bmeconv -s -t255 -r254 -h253 editfont.lbm editfont.spr 13 | bmeconv -p editor.lbm editor.pal 14 | datafile editor.dat filelist.txt 15 | 16 | editdata.c: dat2inc.exe editor.dat 17 | dat2inc editor.dat editdata.c 18 | 19 | worlded3.exe: worlded3.cpp editdata.c stb_image_write.c 20 | g++ worlded3.cpp editdata.c stb_image_write.c bme.c bme_gfx.c bme_io.c bme_win.c bme_kbd.c bme_mou.c -oworlded3.exe -fpermissive -w -march=i386 -static-libstdc++ -static-libgcc -lmingw32 -lSDLmain -lSDL -Wl,-Bstatic -lstdc++ -lpthread -Wl,-Bdynamic 21 | strip worlded3.exe 22 | 23 | spred3.exe: spred3.cpp fileio.c editdata.c 24 | g++ spred3.cpp fileio.c editdata.c bme.c bme_gfx.c bme_io.c bme_win.c bme_kbd.c bme_mou.c -ospred3.exe -fpermissive -w -march=i386 -static-libstdc++ -static-libgcc -lmingw32 -lSDLmain -lSDL -Wl,-Bstatic -lstdc++ -lpthread -Wl,-Bdynamic 25 | strip spred3.exe 26 | 27 | gt2mini.exe: gt2mini.c fileio.c 28 | gcc gt2mini.c fileio.c -ogt2mini.exe 29 | 30 | usecount.exe: usecount.cpp 31 | g++ usecount.cpp -ousecount.exe -w -march=i386 -static-libstdc++ -static-libgcc -lmingw32 -Wl,-Bstatic -lstdc++ -lpthread -Wl,-Bdynamic 32 | strip usecount.exe 33 | 34 | makeef.exe: makeef.cpp 35 | g++ makeef.cpp -omakeef.exe -w -march=i386 -static-libstdc++ -static-libgcc -lmingw32 -Wl,-Bstatic -lstdc++ -lpthread -Wl,-Bdynamic 36 | strip makeef.exe 37 | 38 | makegmod2.exe: makegmod2.cpp 39 | g++ makegmod2.cpp -omakegmod2.exe -w -march=i386 -static-libstdc++ -static-libgcc -lmingw32 -Wl,-Bstatic -lstdc++ -lpthread -Wl,-Bdynamic 40 | strip makegmod2.exe 41 | 42 | pack3.exe: pack3.c 43 | gcc pack3.c -opack3.exe 44 | 45 | pchunk3.exe: pchunk3.c 46 | gcc pchunk3.c -opchunk3.exe 47 | 48 | maked64.exe: maked64.c 49 | gcc maked64.c -omaked64.exe 50 | 51 | symbols.exe: symbols.c 52 | gcc symbols.c -osymbols.exe 53 | 54 | bmeconv.exe: bmeconv.c fileio.c 55 | gcc bmeconv.c fileio.c -obmeconv.exe 56 | 57 | datafile.exe: datafile.c fileio.c 58 | gcc datafile.c fileio.c -odatafile.exe 59 | 60 | dat2inc.exe: dat2inc.c 61 | gcc dat2inc.c -odat2inc.exe 62 | 63 | gfxconv.exe: gfxconv.c fileio.c 64 | gcc gfxconv.c fileio.c -ogfxconv.exe 65 | 66 | filejoin.exe: filejoin.c 67 | gcc filejoin.c -ofilejoin.exe 68 | 69 | filesplit.exe: filesplit.c 70 | gcc filesplit.c -ofilesplit.exe 71 | -------------------------------------------------------------------------------- /tools/SDL.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cadaver/c64gameframework/15eaa821599c860ab94009085d6b340f93f65670/tools/SDL.dll -------------------------------------------------------------------------------- /tools/bme.c: -------------------------------------------------------------------------------- 1 | // 2 | // BME (Blasphemous Multimedia Engine) main module 3 | // 4 | 5 | #include "bme_err.h" 6 | #include "bme_cfg.h" 7 | 8 | int bme_error = BME_OK; 9 | -------------------------------------------------------------------------------- /tools/bme.h: -------------------------------------------------------------------------------- 1 | // BME header file for user applications 2 | 3 | #include 4 | #include "bme_main.h" 5 | #include "bme_cfg.h" 6 | #include "bme_err.h" 7 | #include "bme_snd.h" 8 | #include "bme_gfx.h" 9 | #include "bme_win.h" 10 | #include "bme_kbd.h" 11 | #include "bme_mou.h" 12 | #include "bme_joy.h" 13 | #include "bme_map.h" 14 | #include "bme_txt.h" 15 | #include "bme_io.h" 16 | -------------------------------------------------------------------------------- /tools/bme_cfg.h: -------------------------------------------------------------------------------- 1 | // BME configuration (some static things) 2 | 3 | #define MAX_JOYSTICKS 16 // Maximum joysticks 4 | #define MAX_HANDLES 16 // Up to 16 simultaneus files open from the 5 | // datafile 6 | 7 | #define MAX_COLORS 256 // 8bit oldskool mode 8 | 9 | #define DEFAULT_MAX_SPRFILES 256 // Default maximum of 256 spritefiles, though 10 | // this can be set during running of program 11 | 12 | #define MAX_KEYS 512 13 | 14 | -------------------------------------------------------------------------------- /tools/bme_err.h: -------------------------------------------------------------------------------- 1 | // BME error code header file 2 | 3 | // BME function return codes 4 | 5 | #define BME_OK 1 6 | #define BME_ERROR 0 7 | 8 | // BME detailed error types (in bme_error) 9 | 10 | #define BME_OPEN_ERROR -1 11 | #define BME_READ_ERROR -2 12 | #define BME_WRONG_FORMAT -3 13 | #define BME_OUT_OF_MEMORY -4 14 | #define BME_THREAD_ERROR -5 15 | #define BME_ILLEGAL_CONFIG -6 16 | #define BME_OUT_OF_CHANNELS -7 17 | #define BME_GRAPHICS_ERROR -8 18 | #define BME_SOUND_ERROR -9 19 | 20 | -------------------------------------------------------------------------------- /tools/bme_gfx.h: -------------------------------------------------------------------------------- 1 | // BME graphics module header file 2 | 3 | int gfx_init(unsigned xsize, unsigned ysize, unsigned framerate, unsigned flags); 4 | int gfx_reinit(void); 5 | void gfx_uninit(void); 6 | void gfx_updatepage(void); 7 | void gfx_blitwindow(void); 8 | void gfx_wipepages(void); 9 | void gfx_setclipregion(unsigned left, unsigned top, unsigned right, unsigned bottom); 10 | void gfx_setmaxspritefiles(int num); 11 | void gfx_setmaxcolors(int num); 12 | int gfx_loadpalette(char *name); 13 | void gfx_calcpalette(int fade, int radd, int gadd, int badd); 14 | void gfx_setpalette(void); 15 | int gfx_loadblocks(char *name); 16 | int gfx_loadsprites(int num, char *name); 17 | void gfx_freesprites(int num); 18 | 19 | void gfx_drawblock(int x, int y, unsigned num); 20 | void gfx_drawsprite(int x, int y, unsigned num); 21 | void gfx_drawspritec(int x, int y, unsigned num, int color); 22 | void gfx_drawspritex(int x, int y, unsigned num, Uint8 *xlattable); 23 | void gfx_getspriteinfo(unsigned num); 24 | void gfx_fillscreen(int color); 25 | void gfx_plot(int x, int y, int color); 26 | void gfx_line(int x1, int y1, int x2, int y2, int color); 27 | 28 | extern int gfx_initted; 29 | extern int gfx_scanlinemode; 30 | extern int gfx_preventswitch; 31 | extern int gfx_fullscreen; 32 | extern unsigned gfx_screenxsize; 33 | extern unsigned gfx_screenysize; 34 | extern unsigned gfx_bitsperpixel; 35 | extern unsigned gfx_windowxsize; 36 | extern unsigned gfx_windowysize; 37 | extern unsigned gfx_virtualxsize; 38 | extern unsigned gfx_virtualysize; 39 | extern unsigned gfx_pages; 40 | extern unsigned gfx_framerate; 41 | extern unsigned gfx_nblocks; 42 | extern int gfx_blockxsize; 43 | extern int gfx_blockysize; 44 | extern int spr_xsize; 45 | extern int spr_ysize; 46 | extern int spr_xhotspot; 47 | extern int spr_yhotspot; 48 | extern Uint8 *gfx_vscreen; 49 | extern Uint8 *gfx_blocks; 50 | extern Uint8 gfx_palette[]; 51 | extern BLOCKHEADER *gfx_blockheaders; 52 | -------------------------------------------------------------------------------- /tools/bme_io.c: -------------------------------------------------------------------------------- 1 | // 2 | // BME (Blasphemous Multimedia Engine) datafile IO main module 3 | // 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "bme_main.h" 12 | #include "bme_err.h" 13 | #include "bme_cfg.h" 14 | 15 | typedef struct 16 | { 17 | Uint32 offset; 18 | Sint32 length; 19 | char name[13]; 20 | } HEADER; 21 | 22 | typedef struct 23 | { 24 | HEADER *currentheader; 25 | int filepos; 26 | int open; 27 | } HANDLE; 28 | 29 | static int io_usedatafile = 0; 30 | static HEADER *fileheaders; 31 | static unsigned files; 32 | static char ident[4]; 33 | static char *idstring = "DAT!"; 34 | static HANDLE handle[MAX_HANDLES]; 35 | static FILE *fileptr[MAX_HANDLES] = {NULL}; 36 | static FILE *datafilehandle = NULL; 37 | static unsigned char *datafileptr; 38 | static unsigned char *datafilestart; 39 | 40 | static unsigned freadle32(FILE *index); 41 | static void linkedseek(unsigned pos); 42 | static void linkedread(void *buffer, int length); 43 | static unsigned linkedreadle32(void); 44 | 45 | void io_setfilemode(int usedf) 46 | { 47 | io_usedatafile = usedf; 48 | } 49 | 50 | int io_openlinkeddatafile(unsigned char *ptr) 51 | { 52 | int index; 53 | 54 | if (datafilehandle) fclose(datafilehandle); 55 | datafilehandle = NULL; 56 | 57 | datafilestart = ptr; 58 | linkedseek(0); 59 | 60 | linkedread(ident, 4); 61 | if (memcmp(ident, idstring, 4)) 62 | { 63 | bme_error = BME_WRONG_FORMAT; 64 | return BME_ERROR; 65 | } 66 | 67 | files = linkedreadle32(); 68 | fileheaders = malloc(files * sizeof(HEADER)); 69 | if (!fileheaders) 70 | { 71 | bme_error = BME_OUT_OF_MEMORY; 72 | return BME_ERROR; 73 | } 74 | for (index = 0; index < files; index++) 75 | { 76 | fileheaders[index].offset = linkedreadle32(); 77 | fileheaders[index].length = linkedreadle32(); 78 | linkedread(&fileheaders[index].name, 13); 79 | } 80 | 81 | for (index = 0; index < MAX_HANDLES; index++) handle[index].open = 0; 82 | io_usedatafile = 1; 83 | bme_error = BME_OK; 84 | return BME_OK; 85 | } 86 | 87 | int io_opendatafile(char *name) 88 | { 89 | int index; 90 | 91 | if (name) 92 | { 93 | datafilehandle = fopen(name, "rb"); 94 | if (!datafilehandle) 95 | { 96 | bme_error = BME_OPEN_ERROR; 97 | return BME_ERROR; 98 | } 99 | } 100 | 101 | fread(ident, 4, 1, datafilehandle); 102 | if (memcmp(ident, idstring, 4)) 103 | { 104 | bme_error = BME_WRONG_FORMAT; 105 | return BME_ERROR; 106 | } 107 | 108 | files = freadle32(datafilehandle); 109 | fileheaders = malloc(files * sizeof(HEADER)); 110 | if (!fileheaders) 111 | { 112 | bme_error = BME_OUT_OF_MEMORY; 113 | return BME_ERROR; 114 | } 115 | for (index = 0; index < files; index++) 116 | { 117 | fileheaders[index].offset = freadle32(datafilehandle); 118 | fileheaders[index].length = freadle32(datafilehandle); 119 | fread(&fileheaders[index].name, 13, 1, datafilehandle); 120 | } 121 | 122 | for (index = 0; index < MAX_HANDLES; index++) handle[index].open = 0; 123 | io_usedatafile = 1; 124 | bme_error = BME_OK; 125 | return BME_OK; 126 | } 127 | 128 | // Returns nonnegative file handle if successful, -1 on error 129 | 130 | int io_open(char *name) 131 | { 132 | if (!name) return -1; 133 | 134 | if (!io_usedatafile) 135 | { 136 | int index; 137 | for (index = 0; index < MAX_HANDLES; index++) 138 | { 139 | if (!fileptr[index]) break; 140 | } 141 | if (index == MAX_HANDLES) return -1; 142 | else 143 | { 144 | FILE *file = fopen(name, "rb"); 145 | if (!file) 146 | { 147 | return -1; 148 | } 149 | else 150 | { 151 | fileptr[index] = file; 152 | return index; 153 | } 154 | } 155 | } 156 | else 157 | { 158 | int index; 159 | int namelength; 160 | char namecopy[13]; 161 | 162 | namelength = strlen(name); 163 | if (namelength > 12) namelength = 12; 164 | memcpy(namecopy, name, namelength + 1); 165 | for (index = 0; index < strlen(namecopy); index++) 166 | { 167 | namecopy[index] = toupper(namecopy[index]); 168 | } 169 | 170 | for (index = 0; index < MAX_HANDLES; index++) 171 | { 172 | if (!handle[index].open) 173 | { 174 | int count = files; 175 | handle[index].currentheader = fileheaders; 176 | 177 | while (count) 178 | { 179 | if (!strcmp(namecopy, handle[index].currentheader->name)) 180 | { 181 | handle[index].open = 1; 182 | handle[index].filepos = 0; 183 | return index; 184 | } 185 | count--; 186 | handle[index].currentheader++; 187 | } 188 | return -1; 189 | } 190 | } 191 | return -1; 192 | } 193 | } 194 | 195 | // Returns file position after seek or -1 on error 196 | 197 | int io_lseek(int index, int offset, int whence) 198 | { 199 | if (!io_usedatafile) 200 | { 201 | fseek(fileptr[index], offset, whence); 202 | return ftell(fileptr[index]); 203 | } 204 | else 205 | { 206 | int newpos; 207 | 208 | if ((index < 0) || (index >= MAX_HANDLES)) return -1; 209 | 210 | if (!handle[index].open) return -1; 211 | switch(whence) 212 | { 213 | default: 214 | case SEEK_SET: 215 | newpos = offset; 216 | break; 217 | 218 | case SEEK_CUR: 219 | newpos = offset + handle[index].filepos; 220 | break; 221 | 222 | case SEEK_END: 223 | newpos = offset + handle[index].currentheader->length; 224 | break; 225 | } 226 | if (newpos < 0) newpos = 0; 227 | if (newpos > handle[index].currentheader->length) newpos = handle[index].currentheader->length; 228 | handle[index].filepos = newpos; 229 | return newpos; 230 | } 231 | } 232 | 233 | // Returns number of bytes actually read, -1 on error 234 | 235 | int io_read(int index, void *buffer, int length) 236 | { 237 | if (!io_usedatafile) 238 | { 239 | return fread(buffer, 1, length, fileptr[index]); 240 | } 241 | else 242 | { 243 | int readbytes; 244 | 245 | if ((index < 0) || (index >= MAX_HANDLES)) return -1; 246 | 247 | if (!handle[index].open) return -1; 248 | if (length + handle[index].filepos > handle[index].currentheader->length) 249 | length = handle[index].currentheader->length - handle[index].filepos; 250 | 251 | if (datafilehandle) 252 | { 253 | fseek(datafilehandle, handle[index].currentheader->offset + handle[index].filepos, SEEK_SET); 254 | readbytes = fread(buffer, 1, length, datafilehandle); 255 | } 256 | else 257 | { 258 | linkedseek(handle[index].currentheader->offset + handle[index].filepos); 259 | linkedread(buffer, length); 260 | readbytes = length; 261 | } 262 | handle[index].filepos += readbytes; 263 | return readbytes; 264 | } 265 | } 266 | 267 | // Returns nothing 268 | 269 | void io_close(int index) 270 | { 271 | if (!io_usedatafile) 272 | { 273 | fclose(fileptr[index]); 274 | fileptr[index] = NULL; 275 | } 276 | else 277 | { 278 | if ((index < 0) || (index >= MAX_HANDLES)) return; 279 | 280 | handle[index].open = 0; 281 | } 282 | } 283 | 284 | unsigned io_read8(int index) 285 | { 286 | unsigned char byte; 287 | 288 | io_read(index, &byte, 1); 289 | return byte; 290 | } 291 | 292 | unsigned io_readle16(int index) 293 | { 294 | unsigned char bytes[2]; 295 | 296 | io_read(index, bytes, 2); 297 | return (bytes[1] << 8) | bytes[0]; 298 | } 299 | 300 | unsigned io_readhe16(int index) 301 | { 302 | unsigned char bytes[2]; 303 | 304 | io_read(index, bytes, 2); 305 | return (bytes[0] << 8) | bytes[1]; 306 | } 307 | 308 | unsigned io_readle32(int index) 309 | { 310 | unsigned char bytes[4]; 311 | 312 | io_read(index, bytes, 4); 313 | return (bytes[3] << 24) | (bytes[2] << 16) | (bytes[1] << 8) | bytes[0]; 314 | } 315 | 316 | unsigned io_readhe32(int index) 317 | { 318 | unsigned char bytes[4]; 319 | 320 | io_read(index, bytes, 4); 321 | return (bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3]; 322 | } 323 | 324 | static unsigned freadle32(FILE *file) 325 | { 326 | unsigned char bytes[4]; 327 | 328 | fread(&bytes, 4, 1, file); 329 | return (bytes[3] << 24) | (bytes[2] << 16) | (bytes[1] << 8) | bytes[0]; 330 | } 331 | 332 | static void linkedseek(unsigned pos) 333 | { 334 | datafileptr = &datafilestart[pos]; 335 | } 336 | 337 | static void linkedread(void *buffer, int length) 338 | { 339 | unsigned char *dest = (unsigned char *)buffer; 340 | while (length--) 341 | { 342 | *dest++ = *datafileptr++; 343 | } 344 | } 345 | 346 | static unsigned linkedreadle32(void) 347 | { 348 | unsigned char bytes[4]; 349 | 350 | linkedread(&bytes, 4); 351 | return (bytes[3] << 24) | (bytes[2] << 16) | (bytes[1] << 8) | bytes[0]; 352 | } 353 | 354 | -------------------------------------------------------------------------------- /tools/bme_io.h: -------------------------------------------------------------------------------- 1 | // BME IO module header file 2 | 3 | int io_open(char *name); 4 | int io_lseek(int handle, int bytes, int whence); 5 | int io_read(int handle, void *buffer, int size); 6 | void io_close(int handle); 7 | int io_opendatafile(char *name); 8 | int io_openlinkeddatafile(unsigned char *ptr); 9 | void io_setfilemode(int usedf); 10 | unsigned io_read8(int handle); 11 | unsigned io_readle16(int handle); 12 | unsigned io_readle32(int handle); 13 | unsigned io_readhe16(int handle); 14 | unsigned io_readhe32(int handle); 15 | -------------------------------------------------------------------------------- /tools/bme_joy.c: -------------------------------------------------------------------------------- 1 | // 2 | // BME (Blasphemous Multimedia Engine) joystick module 3 | // 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | #include "bme_main.h" 11 | #include "bme_cfg.h" 12 | #include "bme_win.h" 13 | #include "bme_io.h" 14 | #include "bme_err.h" 15 | 16 | int joy_detect(unsigned id) 17 | { 18 | if (id > MAX_JOYSTICKS) return BME_ERROR; 19 | if (SDL_NumJoysticks() > 0) 20 | { 21 | if (joy[id]) 22 | { 23 | SDL_JoystickClose(joy[id]); 24 | joy[id] = NULL; 25 | } 26 | joy[id] = SDL_JoystickOpen(id); 27 | if (joy[id]) return BME_OK; 28 | else return BME_ERROR; 29 | } 30 | return BME_ERROR; 31 | } 32 | 33 | unsigned joy_getstatus(unsigned id, int threshold) 34 | { 35 | unsigned control = 0; 36 | 37 | if (id > MAX_JOYSTICKS) return 0; 38 | if (!joy[id]) return 0; 39 | 40 | if (joyx[id] < -threshold) control |= JOY_LEFT; 41 | if (joyx[id] > threshold) control |= JOY_RIGHT; 42 | if (joyy[id] < -threshold) control |= JOY_UP; 43 | if (joyy[id] > threshold) control |= JOY_DOWN; 44 | control |= joybuttons[id] << 4; 45 | 46 | return control; 47 | } 48 | -------------------------------------------------------------------------------- /tools/bme_joy.h: -------------------------------------------------------------------------------- 1 | // Joystick functions header file 2 | 3 | int joy_detect(unsigned id); 4 | unsigned joy_getstatus(unsigned id, int threshold); 5 | -------------------------------------------------------------------------------- /tools/bme_kbd.c: -------------------------------------------------------------------------------- 1 | // 2 | // BME (Blasphemous Multimedia Engine) keyboard module 3 | // 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | #include "bme_main.h" 11 | #include "bme_cfg.h" 12 | #include "bme_win.h" 13 | #include "bme_io.h" 14 | #include "bme_err.h" 15 | 16 | int kbd_init(void); 17 | void kbd_uninit(void); 18 | int kbd_waitkey(void); 19 | int kbd_getkey(void); 20 | int kbd_checkkey(int rawcode); 21 | int kbd_getascii(void); 22 | unsigned kbd_getvirtualkey(void); 23 | char *kbd_getkeyname(int rawcode); 24 | 25 | static KEY keyname[] = {{KEY_BACKSPACE, "BACKSPACE"}, 26 | {KEY_CAPSLOCK, "CAPSLOCK"}, 27 | {KEY_ENTER, "ENTER"}, 28 | {KEY_ESC, "ESC"}, 29 | {KEY_NUMLOCK, "NUMLOCK"}, 30 | {KEY_LEFTSHIFT, "SHIFT"}, 31 | {KEY_RIGHTSHIFT, "SHIFT"}, 32 | {KEY_SCROLLLOCK, "SCR. LOCK"}, 33 | {KEY_SPACE, "SPACE"}, 34 | {KEY_TAB, "TAB"}, 35 | {KEY_F1, "F1"}, 36 | {KEY_F2, "F2"}, 37 | {KEY_F3, "F3"}, 38 | {KEY_F4, "F4"}, 39 | {KEY_F5, "F5"}, 40 | {KEY_F6, "F6"}, 41 | {KEY_F7, "F7"}, 42 | {KEY_F8, "F8"}, 43 | {KEY_F9, "F9"}, 44 | {KEY_F10, "F10"}, 45 | {KEY_F11, "F11"}, 46 | {KEY_F12, "F12"}, 47 | {KEY_A, "A"}, 48 | {KEY_N, "N"}, 49 | {KEY_B, "B"}, 50 | {KEY_O, "O"}, 51 | {KEY_C, "C"}, 52 | {KEY_P, "P"}, 53 | {KEY_D, "D"}, 54 | {KEY_Q, "Q"}, 55 | {KEY_E, "E"}, 56 | {KEY_R, "R"}, 57 | {KEY_F, "F"}, 58 | {KEY_S, "S"}, 59 | {KEY_G, "G"}, 60 | {KEY_T, "T"}, 61 | {KEY_H, "H"}, 62 | {KEY_U, "U"}, 63 | {KEY_I, "I"}, 64 | {KEY_V, "V"}, 65 | {KEY_J, "J"}, 66 | {KEY_W, "W"}, 67 | {KEY_K, "K"}, 68 | {KEY_X, "X"}, 69 | {KEY_L, "L"}, 70 | {KEY_Y, "Y"}, 71 | {KEY_M, "M"}, 72 | {KEY_Z, "Z"}, 73 | {KEY_1, "1"}, 74 | {KEY_2, "2"}, 75 | {KEY_3, "3"}, 76 | {KEY_4, "4"}, 77 | {KEY_5, "5"}, 78 | {KEY_6, "6"}, 79 | {KEY_7, "7"}, 80 | {KEY_8, "8"}, 81 | {KEY_9, "9"}, 82 | {KEY_0, "0"}, 83 | {KEY_MINUS, "-"}, 84 | {KEY_EQUAL, "="}, 85 | {KEY_BRACKETL, "["}, 86 | {KEY_BRACKETR, "]"}, 87 | {KEY_SEMICOLON, ";"}, 88 | {KEY_APOST1, "'"}, 89 | {KEY_APOST2, "`"}, 90 | {KEY_COMMA, ","}, 91 | {KEY_COLON, "."}, 92 | {KEY_SLASH, "/"}, 93 | {KEY_BACKSLASH, "\\"}, 94 | {KEY_ALT, "ALT"}, 95 | {KEY_CTRL, "CTRL"}, 96 | {KEY_DEL, "DELETE"}, 97 | {KEY_DOWN, "CRS. DOWN"}, 98 | {KEY_END, "END"}, 99 | {KEY_HOME, "HOME"}, 100 | {KEY_INS, "INSERT"}, 101 | {KEY_LEFT, "CRS. LEFT"}, 102 | {KEY_PGDN, "PAGE DOWN"}, 103 | {KEY_PGUP, "PAGE UP"}, 104 | {KEY_RIGHT, "CRS. RIGHT"}, 105 | {KEY_UP, "CRS. UP"}, 106 | {KEY_WINDOWSL, "WINDOWS KEY"}, 107 | {KEY_WINDOWSR, "WINDOWS KEY"}, 108 | {KEY_MENU, "MENU KEY"}, 109 | {0xff, "?"}}; 110 | 111 | int kbd_init(void) 112 | { 113 | return BME_OK; 114 | } 115 | 116 | void kbd_uninit(void) 117 | { 118 | } 119 | 120 | int kbd_waitkey(void) 121 | { 122 | int index; 123 | 124 | win_asciikey = 0; 125 | for (;;) 126 | { 127 | win_checkmessages(); 128 | 129 | for (index = 0; index < MAX_KEYS; index++) 130 | { 131 | if (win_keytable[index]) 132 | { 133 | win_keytable[index] = 0; 134 | return index; 135 | } 136 | } 137 | 138 | SDL_Delay(15); 139 | } 140 | } 141 | 142 | int kbd_getkey(void) 143 | { 144 | int index; 145 | 146 | for (index = 0; index < MAX_KEYS; index++) 147 | { 148 | if (win_keytable[index]) 149 | { 150 | win_keytable[index] = 0; 151 | return index; 152 | } 153 | } 154 | return 0; 155 | } 156 | 157 | int kbd_checkkey(int rawcode) 158 | { 159 | if (rawcode >= MAX_KEYS) return 0; 160 | if (win_keytable[rawcode]) 161 | { 162 | win_keytable[rawcode] = 0; 163 | return 1; 164 | } 165 | return 0; 166 | } 167 | 168 | int kbd_getascii(void) 169 | { 170 | int key; 171 | 172 | if (win_asciikey) 173 | { 174 | key = win_asciikey; 175 | win_asciikey = 0; 176 | return key; 177 | } 178 | else return 0; 179 | } 180 | 181 | unsigned kbd_getvirtualkey(void) 182 | { 183 | unsigned key; 184 | 185 | if (win_virtualkey) 186 | { 187 | key = win_virtualkey; 188 | win_virtualkey = 0; 189 | return key; 190 | } 191 | else return 0; 192 | } 193 | 194 | char *kbd_getkeyname(int rawcode) 195 | { 196 | KEY *ptr = &keyname[0]; 197 | 198 | while (ptr->rawcode != 255) 199 | { 200 | if (ptr->rawcode == rawcode) 201 | { 202 | return ptr->name; 203 | } 204 | ptr++; 205 | } 206 | return ptr->name; 207 | } 208 | 209 | 210 | -------------------------------------------------------------------------------- /tools/bme_kbd.h: -------------------------------------------------------------------------------- 1 | // BME keyboard functions header file 2 | 3 | int kbd_init(void); 4 | void kbd_uninit(void); 5 | int kbd_waitkey(void); 6 | int kbd_getkey(void); 7 | int kbd_checkkey(int rawcode); 8 | int kbd_getascii(void); 9 | unsigned kbd_getvirtualkey(void); 10 | char *kbd_getkeyname(int rawcode); 11 | -------------------------------------------------------------------------------- /tools/bme_main.h: -------------------------------------------------------------------------------- 1 | // BME main definitions header file 2 | 3 | #define GFX_SCANLINES 1 4 | #define GFX_DOUBLESIZE 2 5 | #define GFX_USE1PAGE 0 6 | #define GFX_USE2PAGES 4 7 | #define GFX_USE3PAGES 8 8 | #define GFX_WAITVBLANK 16 9 | #define GFX_FULLSCREEN 32 10 | #define GFX_WINDOW 64 11 | #define GFX_NOSWITCHING 128 12 | #define GFX_USEDIBSECTION 256 13 | 14 | #define MOUSE_ALWAYS_VISIBLE 0 15 | #define MOUSE_FULLSCREEN_HIDDEN 1 16 | #define MOUSE_ALWAYS_HIDDEN 2 17 | 18 | #define MOUSEB_LEFT 1 19 | #define MOUSEB_RIGHT 2 20 | #define MOUSEB_MIDDLE 4 21 | 22 | #define JOY_LEFT 1 23 | #define JOY_RIGHT 2 24 | #define JOY_UP 4 25 | #define JOY_DOWN 8 26 | #define JOY_FIRE1 16 27 | #define JOY_FIRE2 32 28 | #define JOY_FIRE3 64 29 | #define JOY_FIRE4 128 30 | 31 | #define LEFT 0 32 | #define MIDDLE 128 33 | #define RIGHT 255 34 | 35 | #define B_OFF 0 36 | #define B_SOLID 1 37 | #define B_NOTSOLID 2 38 | 39 | #define MONO 0 40 | #define STEREO 1 41 | #define EIGHTBIT 0 42 | #define SIXTEENBIT 2 43 | 44 | #define VM_OFF 0 45 | #define VM_ON 1 46 | #define VM_ONESHOT 0 47 | #define VM_LOOP 2 48 | #define VM_16BIT 4 49 | 50 | #define KEY_BACKSPACE SDLK_BACKSPACE 51 | #define KEY_CAPSLOCK SDLK_CAPSLOCK 52 | #define KEY_ENTER SDLK_RETURN 53 | #define KEY_ESC SDLK_ESCAPE 54 | #define KEY_ALT SDLK_LALT 55 | #define KEY_CTRL SDLK_LCTRL 56 | #define KEY_RIGHTALT SDLK_RALT 57 | #define KEY_RIGHTCTRL SDLK_RCTRL 58 | #define KEY_LEFTSHIFT SDLK_LSHIFT 59 | #define KEY_RIGHTSHIFT SDLK_RSHIFT 60 | #define KEY_NUMLOCK SDLK_NUMLOCK 61 | #define KEY_SCROLLLOCK SDLK_SCROLLOCK 62 | #define KEY_SPACE SDLK_SPACE 63 | #define KEY_TAB SDLK_TAB 64 | #define KEY_F1 SDLK_F1 65 | #define KEY_F2 SDLK_F2 66 | #define KEY_F3 SDLK_F3 67 | #define KEY_F4 SDLK_F4 68 | #define KEY_F5 SDLK_F5 69 | #define KEY_F6 SDLK_F6 70 | #define KEY_F7 SDLK_F7 71 | #define KEY_F8 SDLK_F8 72 | #define KEY_F9 SDLK_F9 73 | #define KEY_F10 SDLK_F10 74 | #define KEY_F11 SDLK_F11 75 | #define KEY_F12 SDLK_F12 76 | #define KEY_A SDLK_a 77 | #define KEY_N SDLK_n 78 | #define KEY_B SDLK_b 79 | #define KEY_O SDLK_o 80 | #define KEY_C SDLK_c 81 | #define KEY_P SDLK_p 82 | #define KEY_D SDLK_d 83 | #define KEY_Q SDLK_q 84 | #define KEY_E SDLK_e 85 | #define KEY_R SDLK_r 86 | #define KEY_F SDLK_f 87 | #define KEY_S SDLK_s 88 | #define KEY_G SDLK_g 89 | #define KEY_T SDLK_t 90 | #define KEY_H SDLK_h 91 | #define KEY_U SDLK_u 92 | #define KEY_I SDLK_i 93 | #define KEY_V SDLK_v 94 | #define KEY_J SDLK_j 95 | #define KEY_W SDLK_w 96 | #define KEY_K SDLK_k 97 | #define KEY_X SDLK_x 98 | #define KEY_L SDLK_l 99 | #define KEY_Y SDLK_y 100 | #define KEY_M SDLK_m 101 | #define KEY_Z SDLK_z 102 | #define KEY_1 SDLK_1 103 | #define KEY_2 SDLK_2 104 | #define KEY_3 SDLK_3 105 | #define KEY_4 SDLK_4 106 | #define KEY_5 SDLK_5 107 | #define KEY_6 SDLK_6 108 | #define KEY_7 SDLK_7 109 | #define KEY_8 SDLK_8 110 | #define KEY_9 SDLK_9 111 | #define KEY_0 SDLK_0 112 | #define KEY_MINUS SDLK_MINUS 113 | #define KEY_EQUAL SDLK_EQUALS 114 | #define KEY_BRACKETL SDLK_LEFTBRACKET 115 | #define KEY_BRACKETR SDLK_RIGHTBRACKET 116 | #define KEY_SEMICOLON SDLK_SEMICOLON 117 | #define KEY_APOST1 SDLK_QUOTE 118 | #define KEY_APOST2 SDLK_BACKQUOTE 119 | #define KEY_COMMA SDLK_COMMA 120 | #define KEY_COLON SDLK_PERIOD 121 | #define KEY_PERIOD SDLK_PERIOD 122 | #define KEY_SLASH SDLK_SLASH 123 | #define KEY_BACKSLASH SDLK_BACKSLASH 124 | #define KEY_DEL SDLK_DELETE 125 | #define KEY_DOWN SDLK_DOWN 126 | #define KEY_END SDLK_END 127 | #define KEY_HOME SDLK_HOME 128 | #define KEY_INS SDLK_INSERT 129 | #define KEY_LEFT SDLK_LEFT 130 | #define KEY_PGDN SDLK_PAGEDOWN 131 | #define KEY_PGUP SDLK_PAGEUP 132 | #define KEY_RIGHT SDLK_RIGHT 133 | #define KEY_UP SDLK_UP 134 | #define KEY_WINDOWSL SDLK_LSUPER 135 | #define KEY_WINDOWSR SDLK_RSUPER 136 | #define KEY_MENU SDLK_MENU 137 | #define KEY_PAUSE SDLK_PAUSE 138 | #define KEY_KPDIVIDE SDLK_KP_DIVIDE 139 | #define KEY_KPMULTIPLY SDLK_KP_MULTIPLY 140 | #define KEY_KPPLUS SDLK_KP_PLUS 141 | #define KEY_KPMINUS SDLK_KP_MINUS 142 | 143 | 144 | typedef struct 145 | { 146 | Sint8 *start; 147 | Sint8 *repeat; 148 | Sint8 *end; 149 | unsigned char voicemode; 150 | } SAMPLE; 151 | 152 | typedef struct 153 | { 154 | volatile Sint8 *pos; 155 | Sint8 *repeat; 156 | Sint8 *end; 157 | SAMPLE *smp; 158 | unsigned freq; 159 | volatile unsigned fractpos; 160 | int vol; 161 | int mastervol; 162 | unsigned panning; 163 | volatile unsigned voicemode; 164 | } CHANNEL; 165 | 166 | typedef struct 167 | { 168 | unsigned rawcode; 169 | char *name; 170 | } KEY; 171 | 172 | typedef struct 173 | { 174 | Sint16 xsize; 175 | Sint16 ysize; 176 | Sint16 xhot; 177 | Sint16 yhot; 178 | Uint32 offset; 179 | } SPRITEHEADER; 180 | 181 | typedef struct 182 | { 183 | Uint32 type; 184 | Uint32 offset; 185 | } BLOCKHEADER; 186 | 187 | typedef struct 188 | { 189 | Uint8 blocksname[13]; 190 | Uint8 palettename[13]; 191 | } MAPHEADER; 192 | 193 | typedef struct 194 | { 195 | Sint32 xsize; 196 | Sint32 ysize; 197 | Uint8 xdivisor; 198 | Uint8 ydivisor; 199 | Uint8 xwrap; 200 | Uint8 ywrap; 201 | } LAYERHEADER; 202 | 203 | extern int bme_error; 204 | -------------------------------------------------------------------------------- /tools/bme_map.c: -------------------------------------------------------------------------------- 1 | // 2 | // BME (Blasphemous Multimedia Engine) blockmap module 3 | // 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #include "bme_main.h" 10 | #include "bme_gfx.h" 11 | #include "bme_err.h" 12 | #include "bme_cfg.h" 13 | #include "bme_io.h" 14 | 15 | #define MAX_LAYERS 4 16 | #define MAX_STEP 64 17 | 18 | MAPHEADER map_header; 19 | LAYERHEADER map_layer[MAX_LAYERS]; 20 | Uint16 *map_layerdataptr[] = {NULL,NULL,NULL,NULL}; 21 | Uint8 *map_blkinfdata = NULL; 22 | 23 | static BLOCKHEADER map_blkstorage[MAX_STEP]; 24 | 25 | void map_freemap(void); 26 | int map_loadmap(char *name); 27 | void map_drawalllayers(int xpos, int ypos, int xorigin, int yorigin, int xblocks, int yblocks); 28 | void map_drawlayer(int l, int xpos, int ypos, int xorigin, int yorigin, int xblocks, int yblocks); 29 | int map_loadblockinfo(char *name); 30 | Uint8 map_getblockinfo(int l, int xpos, int ypos); 31 | unsigned map_getblocknum(int l, int xpos, int ypos); 32 | void map_setblocknum(int l, int xpos, int ypos, unsigned num); 33 | void map_shiftblocksback(unsigned first, int amount, int step); 34 | void map_shiftblocksforward(unsigned first, int amount, int step); 35 | 36 | int map_loadblockinfo(char *name) 37 | { 38 | int handle; 39 | 40 | if (map_blkinfdata) 41 | { 42 | free(map_blkinfdata); 43 | map_blkinfdata = NULL; 44 | } 45 | map_blkinfdata = malloc((gfx_nblocks+1)*16); 46 | if (!map_blkinfdata) return 0; 47 | memset(map_blkinfdata, 0, (gfx_nblocks+1)*16); 48 | 49 | handle = io_open(name); 50 | if (handle == -1) return 0; 51 | io_read(handle, &map_blkinfdata[0], (gfx_nblocks+1)*16); 52 | io_close(handle); 53 | return 1; 54 | } 55 | 56 | void map_freemap(void) 57 | { 58 | int c; 59 | 60 | for (c = 0; c < MAX_LAYERS; c++) 61 | { 62 | if (map_layerdataptr[c]) 63 | { 64 | free(map_layerdataptr[c]); 65 | map_layerdataptr[c] = NULL; 66 | } 67 | } 68 | } 69 | 70 | int map_loadmap(char *name) 71 | { 72 | int handle, c; 73 | 74 | map_freemap(); 75 | 76 | handle = io_open(name); 77 | if (handle == -1) return 0; 78 | /* Load map header */ 79 | io_read(handle, &map_header, sizeof(MAPHEADER)); 80 | /* Load each layer */ 81 | for (c = 0; c < MAX_LAYERS; c++) 82 | { 83 | map_layer[c].xsize = io_readle32(handle); 84 | map_layer[c].ysize = io_readle32(handle); 85 | map_layer[c].xdivisor = io_read8(handle); 86 | map_layer[c].ydivisor = io_read8(handle); 87 | map_layer[c].xwrap = io_read8(handle); 88 | map_layer[c].ywrap = io_read8(handle); 89 | if ((map_layer[c].xsize) && (map_layer[c].ysize)) 90 | { 91 | int d; 92 | map_layerdataptr[c] = malloc(map_layer[c].xsize*map_layer[c].ysize * sizeof(Uint16)); 93 | if (!map_layerdataptr[c]) 94 | { 95 | io_close(handle); 96 | map_freemap(); 97 | return 0; 98 | } 99 | for (d = 0; d < map_layer[c].xsize * map_layer[c].ysize; d++) 100 | { 101 | map_layerdataptr[c][d] = io_readle16(handle); 102 | } 103 | } 104 | } 105 | io_close(handle); 106 | return 1; 107 | } 108 | 109 | void map_drawalllayers(int xpos, int ypos, int xorigin, int yorigin, int xblocks, int yblocks) 110 | { 111 | int c; 112 | for (c = 0; c < MAX_LAYERS; c++) 113 | { 114 | map_drawlayer(c, xpos, ypos, xorigin, yorigin, xblocks, yblocks); 115 | } 116 | } 117 | 118 | void map_drawlayer(int l, int xpos, int ypos, int xorigin, int yorigin, int xblocks, int yblocks) 119 | { 120 | int x,y; 121 | int realxpos = 0, realypos = 0; 122 | int blockxpos, finexpos; 123 | int blockypos, fineypos; 124 | Uint16 *mapptr; 125 | 126 | /* Check for inactive layer */ 127 | if ((!map_layer[l].xsize) || (!map_layer[l].ysize)) return; 128 | 129 | if (map_layer[l].xdivisor) realxpos = xpos / map_layer[l].xdivisor; 130 | if (map_layer[l].ydivisor) realypos = ypos / map_layer[l].ydivisor; 131 | 132 | if (realxpos < 0) realxpos = 0; 133 | if (realypos < 0) realypos = 0; 134 | 135 | finexpos = realxpos % gfx_blockxsize; 136 | fineypos = realypos % gfx_blockysize; 137 | blockxpos = realxpos / gfx_blockxsize; 138 | blockypos = realypos / gfx_blockysize; 139 | 140 | if (!map_layer[l].xwrap) 141 | { 142 | if ((blockxpos + xblocks-1) > map_layer[l].xsize) 143 | { 144 | if (map_layer[l].xsize - (xblocks - 1) >= 0) 145 | { 146 | blockxpos = map_layer[l].xsize - (xblocks-1); 147 | finexpos = gfx_blockxsize - 1; 148 | } 149 | } 150 | } 151 | 152 | if (!map_layer[l].ywrap) 153 | { 154 | if ((blockypos + yblocks-1) > map_layer[l].ysize) 155 | { 156 | if (map_layer[l].ysize - (yblocks - 1) >= 0) 157 | { 158 | blockypos = map_layer[l].ysize - (yblocks-1); 159 | fineypos = gfx_blockysize - 1; 160 | } 161 | } 162 | } 163 | 164 | blockxpos %= map_layer[l].xsize; 165 | blockypos %= map_layer[l].ysize; 166 | 167 | for (y = 0; y < yblocks; y++) 168 | { 169 | if (blockypos >= map_layer[l].ysize) blockypos = 0; 170 | mapptr = &map_layerdataptr[l][map_layer[l].xsize*blockypos]; 171 | for (x = 0; x < xblocks; x++) 172 | { 173 | int xpos = blockxpos + x; 174 | if (xpos >= map_layer[l].xsize) xpos %= map_layer[l].xsize; 175 | gfx_drawblock(xorigin+(x*gfx_blockxsize)-finexpos, yorigin+(y*gfx_blockysize)-fineypos, mapptr[xpos]); 176 | } 177 | blockypos++; 178 | } 179 | } 180 | 181 | Uint8 map_getblockinfo(int l, int xpos, int ypos) 182 | { 183 | int xfine, yfine; 184 | unsigned blocknum; 185 | 186 | xfine = ((xpos % gfx_blockxsize)*4)/gfx_blockxsize; 187 | yfine = ((ypos % gfx_blockysize)*4)/gfx_blockysize; 188 | xpos /= gfx_blockxsize; 189 | ypos /= gfx_blockysize; 190 | 191 | if (xpos < 0) return 0; 192 | if (xpos >= map_layer[l].xsize) return 0; 193 | if (ypos < 0) return 0; 194 | if (ypos >= map_layer[l].ysize) return 0; 195 | 196 | blocknum = map_layerdataptr[l][map_layer[l].xsize*ypos+xpos]; 197 | if (blocknum > gfx_nblocks) return 0; 198 | return map_blkinfdata[blocknum*16+yfine*4+xfine]; 199 | } 200 | 201 | unsigned map_getblocknum(int l, int xpos, int ypos) 202 | { 203 | xpos /= gfx_blockxsize; 204 | ypos /= gfx_blockysize; 205 | 206 | if (xpos < 0) return 0; 207 | if (xpos >= map_layer[l].xsize) return 0; 208 | if (ypos < 0) return 0; 209 | if (ypos >= map_layer[l].ysize) return 0; 210 | 211 | return map_layerdataptr[l][map_layer[l].xsize*ypos+xpos]; 212 | } 213 | 214 | void map_setblocknum(int l, int xpos, int ypos, unsigned num) 215 | { 216 | if (num > gfx_nblocks) return; 217 | 218 | xpos /= gfx_blockxsize; 219 | ypos /= gfx_blockysize; 220 | 221 | if (xpos < 0) return; 222 | if (xpos >= map_layer[l].xsize) return; 223 | if (ypos < 0) return; 224 | if (ypos >= map_layer[l].ysize) return; 225 | 226 | map_layerdataptr[l][map_layer[l].xsize*ypos+xpos] = num; 227 | } 228 | 229 | void map_shiftblocksback(unsigned first, int amount, int step) 230 | { 231 | BLOCKHEADER *ptr = gfx_blockheaders; 232 | 233 | if (!ptr) return; 234 | 235 | first--; 236 | if (first >= gfx_nblocks) return; 237 | if ((first + amount) > gfx_nblocks) return; 238 | ptr += first; 239 | 240 | if (step > MAX_STEP) return; 241 | if (amount - step < 1) return; 242 | 243 | memmove(map_blkstorage, ptr, sizeof(BLOCKHEADER) * step); 244 | memmove(ptr, &ptr[step], sizeof(BLOCKHEADER) * (amount - step)); 245 | memmove(&ptr[amount - step], map_blkstorage, sizeof(BLOCKHEADER) * step); 246 | } 247 | 248 | void map_shiftblocksforward(unsigned first, int amount, int step) 249 | { 250 | BLOCKHEADER *ptr = gfx_blockheaders; 251 | 252 | if (!ptr) return; 253 | 254 | first--; 255 | if (first >= gfx_nblocks) return; 256 | if ((first + amount) > gfx_nblocks) return; 257 | ptr += first; 258 | 259 | if (step > MAX_STEP) return; 260 | if (amount - step < 1) return; 261 | 262 | memmove(map_blkstorage, &ptr[amount - step], sizeof(BLOCKHEADER) * step); 263 | memmove(&ptr[step], ptr, sizeof(BLOCKHEADER) * (amount - step)); 264 | memmove(ptr, map_blkstorage, sizeof(BLOCKHEADER) * step); 265 | } 266 | 267 | -------------------------------------------------------------------------------- /tools/bme_map.h: -------------------------------------------------------------------------------- 1 | // BME blockmap module header file 2 | 3 | #define MAX_LAYERS 4 4 | 5 | extern MAPHEADER map_header; 6 | extern LAYERHEADER map_layer[MAX_LAYERS]; 7 | extern unsigned short *map_layerdataptr[]; 8 | extern unsigned char *map_blkinfdata; 9 | 10 | void map_freemap(void); 11 | int map_loadmap(char *name); 12 | void map_drawalllayers(int xpos, int ypos, int xorigin, int yorigin, int xblocks, int yblocks); 13 | void map_drawlayer(int l, int xpos, int ypos, int xorigin, int yorigin, int xblocks, int yblocks); 14 | int map_loadblockinfo(char *name); 15 | unsigned map_getblocknum(int l, int xpos, int ypos); 16 | void map_setblocknum(int l, int xpos, int ypos, unsigned num); 17 | unsigned char map_getblockinfo(int l, int xpos, int ypos); 18 | void map_shiftblocksback(unsigned first, int amount, int step); 19 | void map_shiftblocksforward(unsigned first, int amount, int step); 20 | -------------------------------------------------------------------------------- /tools/bme_mou.c: -------------------------------------------------------------------------------- 1 | // 2 | // BME (Blasphemous Multimedia Engine) mouse module 3 | // 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "bme_main.h" 11 | #include "bme_cfg.h" 12 | #include "bme_win.h" 13 | #include "bme_gfx.h" 14 | #include "bme_io.h" 15 | #include "bme_err.h" 16 | 17 | void mou_init(void); 18 | void mou_uninit(void); 19 | void mou_getpos(unsigned *x, unsigned *y); 20 | void mou_getmove(int *dx, int *dy); 21 | unsigned mou_getbuttons(void); 22 | 23 | void mou_init(void) 24 | { 25 | win_mousebuttons = 0; 26 | } 27 | 28 | void mou_uninit(void) 29 | { 30 | } 31 | 32 | void mou_getpos(unsigned *x, unsigned *y) 33 | { 34 | if (!gfx_initted) 35 | { 36 | *x = win_mousexpos; 37 | *y = win_mouseypos; 38 | } 39 | else 40 | { 41 | *x = win_mousexpos * gfx_virtualxsize / gfx_windowxsize; 42 | *y = win_mouseypos * gfx_virtualysize / gfx_windowysize; 43 | } 44 | } 45 | 46 | void mou_getmove(int *dx, int *dy) 47 | { 48 | *dx = win_mousexrel; 49 | *dy = win_mouseyrel; 50 | win_mousexrel = 0; 51 | win_mouseyrel = 0; 52 | 53 | } 54 | 55 | unsigned mou_getbuttons(void) 56 | { 57 | return win_mousebuttons; 58 | } 59 | 60 | -------------------------------------------------------------------------------- /tools/bme_mou.h: -------------------------------------------------------------------------------- 1 | // BME mouse functions header file 2 | 3 | void mou_init(void); 4 | void mou_uninit(void); 5 | void mou_setmode(int mode); 6 | void mou_getpos(unsigned *x, unsigned *y); 7 | void mou_getmove(int *dx, int *dy); 8 | unsigned mou_getbuttons(void); 9 | -------------------------------------------------------------------------------- /tools/bme_raw.c: -------------------------------------------------------------------------------- 1 | // 2 | // BME (Blasphemous Multimedia Engine) raw samples module 3 | // 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | #include "bme_io.h" 11 | #include "bme_main.h" 12 | #include "bme_snd.h" 13 | #include "bme_cfg.h" 14 | #include "bme_err.h" 15 | 16 | SAMPLE *snd_loadrawsample(char *name, int repeat, int end, unsigned char voicemode) 17 | { 18 | int length; 19 | int handle; 20 | SAMPLE *smp; 21 | 22 | bme_error = BME_OPEN_ERROR; 23 | handle = io_open(name); 24 | if (handle == -1) return NULL; 25 | length = io_lseek(handle, 0, SEEK_END); 26 | if (length == -1) 27 | { 28 | io_close(handle); 29 | return NULL; 30 | } 31 | io_lseek(handle, 0, SEEK_SET); 32 | smp = snd_allocsample(length); 33 | if (!smp) 34 | { 35 | io_close(handle); 36 | return NULL; 37 | } 38 | if (end == 0) end = length; 39 | if (end > length) end = length; 40 | if (repeat > length - 1) repeat = length - 1; 41 | bme_error = BME_READ_ERROR; 42 | if (io_read(handle, smp->start, length) != length) 43 | { 44 | snd_freesample(smp); 45 | io_close(handle); 46 | return NULL; 47 | } 48 | io_close(handle); 49 | smp->repeat = smp->start + repeat; 50 | smp->end = smp->start + end; 51 | smp->voicemode = voicemode | VM_ON; 52 | snd_ipcorrect(smp); 53 | bme_error = BME_OK; 54 | return smp; 55 | } 56 | -------------------------------------------------------------------------------- /tools/bme_smp.c: -------------------------------------------------------------------------------- 1 | // 2 | // BME (Blasphemous Multimedia Engine) sample support main module 3 | // 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | #include "bme_err.h" 11 | #include "bme_main.h" 12 | #include "bme_snd.h" 13 | #include "bme_cfg.h" 14 | 15 | SAMPLE *snd_allocsample(int length) 16 | { 17 | SAMPLE *smp; 18 | 19 | bme_error = BME_OUT_OF_MEMORY; 20 | smp = (SAMPLE *)malloc(sizeof (SAMPLE)); 21 | if (!smp) return NULL; 22 | smp->start = malloc(length); 23 | if (!smp->start) 24 | { 25 | snd_freesample(smp); 26 | return NULL; 27 | } 28 | smp->repeat = NULL; 29 | smp->end = NULL; 30 | bme_error = BME_OK; 31 | return smp; 32 | } 33 | 34 | void snd_freesample(SAMPLE *smp) 35 | { 36 | int c; 37 | CHANNEL *chptr; 38 | 39 | if (!smp) return; 40 | 41 | // Go thru all channels; if that sample is playing then stop the 42 | // channel; we don't want a crash or noise! 43 | 44 | chptr = &snd_channel[0]; 45 | for (c = snd_channels; c > 0; c--) 46 | { 47 | if (chptr->smp == smp) 48 | { 49 | chptr->smp = NULL; 50 | chptr->voicemode = VM_OFF; 51 | } 52 | chptr++; 53 | } 54 | 55 | // Free the sample data and then the sample structure itself 56 | 57 | if (smp->start) free(smp->start); 58 | free(smp); 59 | } 60 | 61 | void snd_ipcorrect(SAMPLE *smp) 62 | { 63 | } 64 | 65 | void snd_playsample(SAMPLE *smp, unsigned chnum, unsigned frequency, unsigned char volume, unsigned char panning) 66 | { 67 | CHANNEL *chptr; 68 | 69 | if (!smp) return; 70 | if (!snd_sndinitted) return; 71 | if (chnum >= (unsigned)snd_channels) return; 72 | chptr = &snd_channel[chnum]; 73 | chptr->voicemode = VM_OFF; 74 | chptr->pos = smp->start; 75 | chptr->repeat = smp->repeat; 76 | chptr->end = smp->end; 77 | chptr->smp = smp; 78 | chptr->fractpos = 0; 79 | chptr->freq = frequency; 80 | chptr->vol = volume; 81 | chptr->panning = panning; 82 | chptr->voicemode = smp->voicemode; 83 | } 84 | 85 | void snd_stopsample(unsigned chnum) 86 | { 87 | CHANNEL *chptr; 88 | 89 | if (!snd_sndinitted) return; 90 | if (chnum >= (unsigned)snd_channels) return; 91 | chptr = &snd_channel[chnum]; 92 | chptr->voicemode = VM_OFF; 93 | chptr->smp = NULL; 94 | } 95 | 96 | void snd_preventdistortion(unsigned active_channels) 97 | { 98 | int count; 99 | unsigned char mastervol; 100 | 101 | if (!snd_sndinitted) return; 102 | if (active_channels < 2) mastervol = 255; 103 | else mastervol = 256 / active_channels; 104 | for (count = 0; count < snd_channels; count++) 105 | { 106 | snd_setmastervolume(count, mastervol); 107 | } 108 | } 109 | 110 | void snd_setmastervolume(unsigned chnum, unsigned char mastervol) 111 | { 112 | CHANNEL *chptr; 113 | 114 | if (!snd_sndinitted) return; 115 | if (chnum >= (unsigned)snd_channels) return; 116 | chptr = &snd_channel[chnum]; 117 | chptr->mastervol = mastervol; 118 | } 119 | 120 | void snd_setmusicmastervolume(unsigned musicchannels, unsigned char mastervol) 121 | { 122 | CHANNEL *chptr = &snd_channel[0]; 123 | int count; 124 | 125 | if (!snd_sndinitted) return; 126 | if (musicchannels > (unsigned)snd_channels) musicchannels = snd_channels; 127 | for (count = 0; (unsigned)count < musicchannels; count++) 128 | { 129 | chptr->mastervol = mastervol; 130 | chptr++; 131 | } 132 | } 133 | 134 | void snd_setsfxmastervolume(unsigned musicchannels, unsigned char mastervol) 135 | { 136 | CHANNEL *chptr; 137 | int count; 138 | 139 | if (!snd_sndinitted) return; 140 | if (musicchannels >= (unsigned)snd_channels) return; 141 | chptr = &snd_channel[musicchannels]; 142 | for (count = musicchannels; count < snd_channels; count++) 143 | { 144 | chptr->mastervol = mastervol; 145 | chptr++; 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /tools/bme_snd.h: -------------------------------------------------------------------------------- 1 | // Sound functions header file 2 | 3 | int snd_init(unsigned mixrate, unsigned mixmode, unsigned bufferlength, unsigned channels, int usedirectsound); 4 | void snd_uninit(void); 5 | void snd_setcustommixer(void (*custommixer)(Sint32 *dest, unsigned samples)); 6 | SAMPLE *snd_allocsample(int length); 7 | void snd_freesample(SAMPLE *smp); 8 | void snd_playsample(SAMPLE *smp, unsigned chnum, unsigned frequency, unsigned char volume, unsigned char panning); 9 | void snd_ipcorrect(SAMPLE *smp); 10 | void snd_stopsample(unsigned chnum); 11 | void snd_preventdistortion(unsigned channels); 12 | void snd_setmastervolume(unsigned chnum, unsigned char mastervol); 13 | void snd_setmusicmastervolume(unsigned musicchannels, unsigned char mastervol); 14 | void snd_setsfxmastervolume(unsigned musicchannels, unsigned char mastervol); 15 | SAMPLE *snd_loadrawsample(char *name, int repeat, int end, unsigned char voicemode); 16 | SAMPLE *snd_loadwav(char *name); 17 | int snd_loadxm(char *name); 18 | void snd_freexm(void); 19 | void snd_playxm(int pos); 20 | void snd_stopxm(void); 21 | unsigned char snd_getxmpos(void); 22 | unsigned char snd_getxmline(void); 23 | unsigned char snd_getxmtick(void); 24 | unsigned char snd_getxmchannels(void); 25 | char *snd_getxmname(void); 26 | int snd_loadmod(char *name); 27 | void snd_freemod(void); 28 | void snd_playmod(int pos); 29 | void snd_stopmod(void); 30 | unsigned char snd_getmodpos(void); 31 | unsigned char snd_getmodline(void); 32 | unsigned char snd_getmodtick(void); 33 | unsigned char snd_getmodchannels(void); 34 | char *snd_getmodname(void); 35 | int snd_loads3m(char *name); 36 | void snd_frees3m(void); 37 | void snd_plays3m(int pos); 38 | void snd_stops3m(void); 39 | unsigned char snd_gets3mpos(void); 40 | unsigned char snd_gets3mline(void); 41 | unsigned char snd_gets3mtick(void); 42 | unsigned char snd_gets3mchannels(void); 43 | char *snd_gets3mname(void); 44 | 45 | extern void (*snd_player)(void); 46 | extern CHANNEL *snd_channel; 47 | extern int snd_sndinitted; 48 | extern int snd_bpmtempo; 49 | extern int snd_bpmcount; 50 | extern int snd_channels; 51 | extern int snd_buffers; 52 | extern unsigned snd_mixmode; 53 | extern unsigned snd_mixrate; 54 | -------------------------------------------------------------------------------- /tools/bme_tbl.c: -------------------------------------------------------------------------------- 1 | // 2 | // BME (Blasphemous Multimedia Engine) music player tables 3 | // 4 | 5 | // Multi retrig tables 6 | 7 | signed char retrigaddtable[] = 8 | { 9 | 0, -1, -2, -4, -8, -16, 0, 0, 0, +1, +2, +4, +8, +16, 0, 0 10 | }; 11 | signed char retrigmultable[] = 12 | { 13 | 0, 0, 0, 0, 0, 0, 11, 8, 0, 0, 0, 0, 0, 0, 24, 32 14 | }; 15 | 16 | // Conversion table from XM instr. vibrato types to standard vibrato types 17 | 18 | unsigned char vibratotypetable[] = 19 | { 20 | 0, 2, 1, 0 21 | }; 22 | 23 | // Vibrato tables (used both for normal & instrument vibrato) 24 | 25 | signed char vibratotable[4][256] = 26 | { 27 | { 28 | 0, -2, -3, -5, -6, -8, -9, -11, -12, -14, -16, -17, -19, -20, -22, -23, 29 | -24, -26, -27, -29, -30, -32, -33, -34, -36, -37, -38, -39, -41, -42, -43, -44, 30 | -45, -46, -47, -48, -49, -50, -51, -52, -53, -54, -55, -56, -56, -57, -58, -59, 31 | -59, -60, -60, -61, -61, -62, -62, -62, -63, -63, -63, -64, -64, -64, -64, -64, 32 | -64, -64, -64, -64, -64, -64, -63, -63, -63, -62, -62, -62, -61, -61, -60, -60, 33 | -59, -59, -58, -57, -56, -56, -55, -54, -53, -52, -51, -50, -49, -48, -47, -46, 34 | -45, -44, -43, -42, -41, -39, -38, -37, -36, -34, -33, -32, -30, -29, -27, -26, 35 | -24, -23, -22, -20, -19, -17, -16, -14, -12, -11, -9, -8, -6, -5, -3, -2, 36 | 0, 2, 3, 5, 6, 8, 9, 11, 12, 14, 16, 17, 19, 20, 22, 23, 37 | 24, 26, 27, 29, 30, 32, 33, 34, 36, 37, 38, 39, 41, 42, 43, 44, 38 | 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, 39 | 59, 60, 60, 61, 61, 62, 62, 62, 63, 63, 63, 64, 64, 64, 64, 64, 40 | 64, 64, 64, 64, 64, 64, 63, 63, 63, 62, 62, 62, 61, 61, 60, 60, 41 | 59, 59, 58, 57, 56, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 42 | 45, 44, 43, 42, 41, 39, 38, 37, 36, 34, 33, 32, 30, 29, 27, 26, 43 | 24, 23, 22, 20, 19, 17, 16, 14, 12, 11, 9, 8, 6, 5, 3, 2 44 | }, 45 | { 46 | 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 47 | 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 48 | 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 49 | 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 50 | 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 51 | 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 52 | 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 53 | 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 54 | -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, 55 | -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, 56 | -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, 57 | -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, 58 | -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, 59 | -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, 60 | -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, 61 | -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64 62 | }, 63 | { 64 | 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 65 | 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 66 | 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 67 | 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31, 31, 68 | 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37, 38, 38, 39, 39, 69 | 40, 40, 41, 41, 42, 42, 43, 43, 44, 44, 45, 45, 46, 46, 47, 47, 70 | 48, 48, 49, 49, 50, 50, 51, 51, 52, 52, 53, 53, 54, 54, 55, 55, 71 | 56, 56, 57, 57, 58, 58, 59, 59, 60, 60, 61, 61, 62, 62, 63, 63, 72 | -64, -64, -63, -63, -62, -62, -61, -61, -60, -60, -59, -59, -58, -58, -57, -57, 73 | -56, -56, -55, -55, -54, -54, -53, -53, -52, -52, -51, -51, -50, -50, -49, -49, 74 | -48, -48, -47, -47, -46, -46, -45, -45, -44, -44, -43, -43, -42, -42, -41, -41, 75 | -40, -40, -39, -39, -38, -38, -37, -37, -36, -36, -35, -35, -34, -34, -33, -33, 76 | -32, -32, -31, -31, -30, -30, -29, -29, -28, -28, -27, -27, -26, -26, -25, -25, 77 | -24, -24, -23, -23, -22, -22, -21, -21, -20, -20, -19, -19, -18, -18, -17, -17, 78 | -16, -16, -15, -15, -14, -14, -13, -13, -12, -12, -11, -11, -10, -10, -9, -9, 79 | -8, -8, -7, -7, -6, -6, -5, -5, -4, -4, -3, -3, -2, -2, -1, -1 80 | }, 81 | { 82 | 0, 0, -1, -1, -2, -2, -3, -3, -4, -4, -5, -5, -6, -6, -7, -7, 83 | -8, -8, -9, -9, -10, -10, -11, -11, -12, -12, -13, -13, -14, -14, -15, -15, 84 | -16, -16, -17, -17, -18, -18, -19, -19, -20, -20, -21, -21, -22, -22, -23, -23, 85 | -24, -24, -25, -25, -26, -26, -27, -27, -28, -28, -29, -29, -30, -30, -31, -31, 86 | -32, -32, -33, -33, -34, -34, -35, -35, -36, -36, -37, -37, -38, -38, -39, -39, 87 | -40, -40, -41, -41, -42, -42, -43, -43, -44, -44, -45, -45, -46, -46, -47, -47, 88 | -48, -48, -49, -49, -50, -50, -51, -51, -52, -52, -53, -53, -54, -54, -55, -55, 89 | -56, -56, -57, -57, -58, -58, -59, -59, -60, -60, -61, -61, -62, -62, -63, -63, 90 | 64, 64, 63, 63, 62, 62, 61, 61, 60, 60, 59, 59, 58, 58, 57, 57, 91 | 56, 56, 55, 55, 54, 54, 53, 53, 52, 52, 51, 51, 50, 50, 49, 49, 92 | 48, 48, 47, 47, 46, 46, 45, 45, 44, 44, 43, 43, 42, 42, 41, 41, 93 | 40, 40, 39, 39, 38, 38, 37, 37, 36, 36, 35, 35, 34, 34, 33, 33, 94 | 32, 32, 31, 31, 30, 30, 29, 29, 28, 28, 27, 27, 26, 26, 25, 25, 95 | 24, 24, 23, 23, 22, 22, 21, 21, 20, 20, 19, 19, 18, 18, 17, 17, 96 | 16, 16, 15, 15, 14, 14, 13, 13, 12, 12, 11, 11, 10, 10, 9, 9, 97 | 8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1 98 | } 99 | }; 100 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /tools/bme_tbl.h: -------------------------------------------------------------------------------- 1 | // Internal header file: tables needed in module playing 2 | 3 | extern signed char retrigaddtable[]; 4 | extern signed char retrigmultable[]; 5 | extern unsigned char vibratotypetable[]; 6 | extern signed char vibratotable[4][256]; 7 | -------------------------------------------------------------------------------- /tools/bme_txt.c: -------------------------------------------------------------------------------- 1 | // 2 | // BME (Blasphemous Multimedia Engine) text printing module 3 | // 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | #include "bme_main.h" 11 | #include "bme_gfx.h" 12 | #include "bme_err.h" 13 | #include "bme_cfg.h" 14 | 15 | int txt_lastx, txt_lasty; 16 | int txt_spacing = -1; 17 | 18 | // Prototypes 19 | 20 | void txt_print(int x, int y, unsigned spritefile, char *string); 21 | void txt_printcenter(int y, unsigned spritefile, char *string); 22 | void txt_printx(int x, int y, unsigned spritefile, char *string, unsigned char *xlattable); 23 | void txt_printcenterx(int y, unsigned spritefile, char *string, unsigned char *xlattable); 24 | 25 | void txt_print(int x, int y, unsigned spritefile, char *string) 26 | { 27 | spritefile <<= 16; 28 | while (*string) 29 | { 30 | unsigned num = *string; 31 | if (num >= 96) num -= 96; // Lowercase ASCII 32 | if (num >= 64) num -= 64; // Uppercase ASCII 33 | 34 | gfx_drawsprite(x, y, spritefile + num + 1); 35 | x += spr_xsize + txt_spacing; 36 | string++; 37 | } 38 | txt_lastx = x; 39 | txt_lasty = y; 40 | } 41 | 42 | void txt_printcenter(int y, unsigned spritefile, char *string) 43 | { 44 | int x = 0; 45 | char *cstring = string; 46 | spritefile <<= 16; 47 | 48 | while (*cstring) 49 | { 50 | unsigned num = *cstring; 51 | if (num >= 96) num -= 96; // Lowercase ASCII 52 | if (num >= 64) num -= 64; // Uppercase ASCII 53 | 54 | gfx_getspriteinfo(spritefile + num + 1); 55 | x += spr_xsize + txt_spacing; 56 | cstring++; 57 | } 58 | x = 160 - x / 2; 59 | 60 | while (*string) 61 | { 62 | unsigned num = *string; 63 | if (num >= 96) num -= 96; // Lowercase ASCII 64 | if (num >= 64) num -= 64; // Uppercase ASCII 65 | 66 | gfx_drawsprite(x, y, spritefile + num + 1); 67 | x += spr_xsize + txt_spacing; 68 | string++; 69 | } 70 | txt_lastx = x; 71 | txt_lasty = y; 72 | } 73 | 74 | void txt_printx(int x, int y, unsigned spritefile, char *string, unsigned char *xlattable) 75 | { 76 | spritefile <<= 16; 77 | while (*string) 78 | { 79 | unsigned num = *string; 80 | if (num >= 96) num -= 96; // Lowercase ASCII 81 | if (num >= 64) num -= 64; // Uppercase ASCII 82 | 83 | gfx_drawspritex(x, y, spritefile + num + 1, xlattable); 84 | x += spr_xsize + txt_spacing; 85 | string++; 86 | } 87 | txt_lastx = x; 88 | txt_lasty = y; 89 | } 90 | 91 | void txt_printcenterx(int y, unsigned spritefile, char *string, unsigned char *xlattable) 92 | { 93 | int x = 0; 94 | char *cstring = string; 95 | spritefile <<= 16; 96 | 97 | while (*cstring) 98 | { 99 | unsigned num = *cstring; 100 | if (num >= 96) num -= 96; // Lowercase ASCII 101 | if (num >= 64) num -= 64; // Uppercase ASCII 102 | 103 | gfx_getspriteinfo(spritefile + num + 1); 104 | x += spr_xsize + txt_spacing; 105 | cstring++; 106 | } 107 | x = 160 - x / 2; 108 | 109 | while (*string) 110 | { 111 | unsigned num = *string; 112 | if (num >= 96) num -= 96; // Lowercase ASCII 113 | if (num >= 64) num -= 64; // Uppercase ASCII 114 | 115 | gfx_drawspritex(x, y, spritefile + num + 1, xlattable); 116 | x += spr_xsize + txt_spacing; 117 | string++; 118 | } 119 | txt_lastx = x; 120 | txt_lasty = y; 121 | } 122 | -------------------------------------------------------------------------------- /tools/bme_txt.h: -------------------------------------------------------------------------------- 1 | // BME text printing module header file 2 | 3 | void txt_print(int x, int y, unsigned spritefile, char *string); 4 | void txt_printcenter(int y, unsigned spritefile, char *string); 5 | void txt_printx(int x, int y, unsigned spritefile, char *string, unsigned char *xlattable); 6 | void txt_printcenterx(int y, unsigned spritefile, char *string, unsigned char *xlattable); 7 | 8 | extern int txt_lastx; 9 | extern int txt_lasty; 10 | extern int txt_spacing; 11 | -------------------------------------------------------------------------------- /tools/bme_wav.c: -------------------------------------------------------------------------------- 1 | // 2 | // BME (Blasphemous Multimedia Engine) WAV samples module 3 | // 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | #include "bme_io.h" 11 | #include "bme_main.h" 12 | #include "bme_snd.h" 13 | #include "bme_cfg.h" 14 | #include "bme_err.h" 15 | 16 | typedef struct 17 | { 18 | Uint8 rifftext[4]; 19 | Uint32 totallength; 20 | Uint8 wavetext[4]; 21 | Uint8 formattext[4]; 22 | Uint32 formatlength; 23 | Uint16 format; 24 | Uint16 channels; 25 | Uint32 freq; 26 | Uint32 avgbytes; 27 | Uint16 blockalign; 28 | Uint16 bits; 29 | Uint8 datatext[4]; 30 | Uint32 datalength; 31 | } WAV_HEADER; 32 | 33 | SAMPLE *snd_loadwav(char *name) 34 | { 35 | int length; 36 | int reallength; 37 | int handle; 38 | SAMPLE *smp; 39 | WAV_HEADER header; 40 | 41 | // Try to open 42 | 43 | bme_error = BME_OPEN_ERROR; 44 | handle = io_open(name); 45 | if (handle == -1) return NULL; 46 | 47 | // Read identification 48 | 49 | memset(&header, 0, sizeof header); 50 | io_read(handle, &header.rifftext, 4); 51 | header.totallength = io_readle32(handle); 52 | io_read(handle, &header.wavetext, 4); 53 | 54 | bme_error = BME_WRONG_FORMAT; 55 | if (memcmp("RIFF", header.rifftext, 4)) 56 | { 57 | io_close(handle); 58 | return NULL; 59 | } 60 | if (memcmp("WAVE", header.wavetext, 4)) 61 | { 62 | io_close(handle); 63 | return NULL; 64 | } 65 | 66 | // Search for the FORMAT chunk 67 | 68 | for (;;) 69 | { 70 | bme_error = BME_READ_ERROR; 71 | io_read(handle, &header.formattext, 4); 72 | header.formatlength = io_readle32(handle); 73 | if (!memcmp("fmt ", &header.formattext, 4)) break; 74 | if (io_lseek(handle, header.formatlength, SEEK_CUR) == -1) 75 | { 76 | io_close(handle); 77 | return NULL; 78 | } 79 | } 80 | // Read in the FORMAT chunk 81 | 82 | header.format = io_readle16(handle); 83 | header.channels = io_readle16(handle); 84 | header.freq = io_readle32(handle); 85 | header.avgbytes = io_readle32(handle); 86 | header.blockalign = io_readle16(handle); 87 | header.bits = io_readle16(handle); 88 | 89 | // Skip data if the format chunk was bigger than what we use 90 | 91 | if (io_lseek(handle, header.formatlength - 16, SEEK_CUR) == -1) 92 | { 93 | io_close(handle); 94 | return NULL; 95 | } 96 | 97 | // Check for correct format 98 | 99 | bme_error = BME_WRONG_FORMAT; 100 | if (header.format != 1) 101 | { 102 | io_close(handle); 103 | return NULL; 104 | } 105 | 106 | // Search for the DATA chunk 107 | 108 | for (;;) 109 | { 110 | bme_error = BME_READ_ERROR; 111 | io_read(handle, &header.datatext, 4); 112 | header.datalength = io_readle32(handle); 113 | if (!memcmp("data", &header.datatext, 4)) break; 114 | if (io_lseek(handle, header.datalength, SEEK_CUR) == -1) 115 | { 116 | io_close(handle); 117 | return NULL; 118 | } 119 | } 120 | // Allocate sample, load audio data, do processing (unsigned->signed, 121 | // stereo->mono) 122 | 123 | length = header.datalength; 124 | reallength = length; 125 | if (header.channels == 2) reallength >>= 1; 126 | smp = snd_allocsample(reallength); 127 | if (!smp) 128 | { 129 | io_close(handle); 130 | return NULL; 131 | } 132 | if (header.channels == 2) 133 | { 134 | if (header.bits == 16) 135 | { 136 | unsigned count; 137 | Sint16 *buffer; 138 | Sint16 *src; 139 | Sint16 *dest; 140 | 141 | bme_error = BME_OUT_OF_MEMORY; 142 | buffer = malloc(length); 143 | if (!buffer) 144 | { 145 | snd_freesample(smp); 146 | io_close(handle); 147 | return NULL; 148 | } 149 | count = 0; 150 | while (count < (length >> 2)) 151 | { 152 | buffer[count] = io_readle16(handle); 153 | count++; 154 | } 155 | src = buffer; 156 | dest = (Sint16 *)smp->start; 157 | count = length >> 2; 158 | while (count--) 159 | { 160 | int average = (src[0] + src[1]) / 2; 161 | *dest = average; 162 | src += 2; 163 | dest++; 164 | } 165 | free(buffer); 166 | smp->repeat = smp->start; 167 | smp->end = smp->start + reallength; 168 | smp->voicemode = VM_ON | VM_16BIT; 169 | } 170 | else 171 | { 172 | unsigned count; 173 | Uint8 *buffer; 174 | Uint8 *src; 175 | Sint8 *dest; 176 | 177 | bme_error = BME_OUT_OF_MEMORY; 178 | buffer = malloc(length); 179 | if (!buffer) 180 | { 181 | snd_freesample(smp); 182 | io_close(handle); 183 | return NULL; 184 | } 185 | count = 0; 186 | while (count < (length >> 1)) 187 | { 188 | buffer[count] = io_readle16(handle); 189 | count++; 190 | } 191 | src = buffer; 192 | dest = smp->start; 193 | count = length >> 1; 194 | while (count--) 195 | { 196 | int average = (src[0] + src[1] - 0x100) / 2; 197 | *dest = average; 198 | src += 2; 199 | dest++; 200 | } 201 | free(buffer); 202 | smp->repeat = smp->start; 203 | smp->end = smp->start + reallength; 204 | smp->voicemode = VM_ON; 205 | } 206 | } 207 | else 208 | { 209 | if (header.bits == 16) 210 | { 211 | unsigned count = 0; 212 | Sint16 *buffer = (Sint16 *)smp->start; 213 | 214 | while (count < (length >> 1)) 215 | { 216 | buffer[count] = io_readle16(handle); 217 | } 218 | smp->repeat = smp->start; 219 | smp->end = smp->start + length; 220 | smp->voicemode = VM_ON | VM_16BIT; 221 | } 222 | else 223 | { 224 | unsigned count = length; 225 | Sint8 *src = smp->start; 226 | 227 | bme_error = BME_READ_ERROR; 228 | if (io_read(handle, smp->start, length) != length) 229 | { 230 | snd_freesample(smp); 231 | io_close(handle); 232 | return NULL; 233 | } 234 | while (count--) 235 | { 236 | *src += 0x80; 237 | src++; 238 | } 239 | smp->repeat = smp->start; 240 | smp->end = smp->start + length; 241 | smp->voicemode = VM_ON; 242 | } 243 | } 244 | bme_error = BME_OK; 245 | io_close(handle); 246 | return smp; 247 | } 248 | -------------------------------------------------------------------------------- /tools/bme_win.c: -------------------------------------------------------------------------------- 1 | // 2 | // BME (Blasphemous Multimedia Engine) windows & timing module 3 | // 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | #include "bme_main.h" 11 | #include "bme_gfx.h" 12 | #include "bme_mou.h" 13 | #include "bme_io.h" 14 | #include "bme_err.h" 15 | #include "bme_cfg.h" 16 | 17 | SDL_Joystick *joy[MAX_JOYSTICKS] = {NULL}; 18 | Sint16 joyx[MAX_JOYSTICKS]; 19 | Sint16 joyy[MAX_JOYSTICKS]; 20 | Uint32 joybuttons[MAX_JOYSTICKS]; 21 | 22 | // Prototypes 23 | 24 | int win_openwindow(char *appname, char *icon); 25 | void win_closewindow(void); 26 | void win_messagebox(char *string); 27 | void win_checkmessages(void); 28 | int win_getspeed(int framerate); 29 | void win_setmousemode(int mode); 30 | 31 | // Global variables 32 | 33 | int win_fullscreen = 0; // By default windowed 34 | int win_windowinitted = 0; 35 | int win_quitted = 0; 36 | unsigned char win_keytable[MAX_KEYS] = {0}; 37 | unsigned char win_asciikey = 0; 38 | unsigned win_virtualkey = 0; 39 | unsigned win_mousexpos = 0; 40 | unsigned win_mouseypos = 0; 41 | unsigned win_mousexrel = 0; 42 | unsigned win_mouseyrel = 0; 43 | unsigned win_mousebuttons = 0; 44 | int win_mousemode = MOUSE_FULLSCREEN_HIDDEN; 45 | unsigned char win_keystate[MAX_KEYS] = {0}; 46 | 47 | // Static variables 48 | 49 | static int win_lasttime = 0; 50 | static int win_currenttime = 0; 51 | static int win_framecounter = 0; 52 | static int win_activateclick = 0; 53 | 54 | int win_openwindow(char *appname, char *icon) 55 | { 56 | if (!win_windowinitted) 57 | { 58 | if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK) < 0) 59 | { 60 | return BME_ERROR; 61 | } 62 | atexit(SDL_Quit); 63 | win_windowinitted = 1; 64 | } 65 | 66 | SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); 67 | SDL_EnableUNICODE(1); 68 | SDL_WM_SetCaption(appname, icon); 69 | return BME_OK; 70 | } 71 | 72 | void win_closewindow(void) 73 | { 74 | } 75 | 76 | void win_messagebox(char *string) 77 | { 78 | return; 79 | } 80 | 81 | int win_getspeed(int framerate) 82 | { 83 | // Note: here 1/10000th of a second accuracy is used (although 84 | // timer resolution is only millisecond) for minimizing 85 | // inaccuracy in frame duration calculation -> smoother screen 86 | // update 87 | 88 | int frametime = 10000 / framerate; 89 | int frames = 0; 90 | 91 | while (!frames) 92 | { 93 | win_checkmessages(); 94 | 95 | win_lasttime = win_currenttime; 96 | win_currenttime = SDL_GetTicks(); 97 | 98 | win_framecounter += (win_currenttime - win_lasttime)*10; 99 | frames = win_framecounter / frametime; 100 | win_framecounter -= frames * frametime; 101 | 102 | if (!frames) SDL_Delay((frametime - win_framecounter)/10); 103 | } 104 | 105 | return frames; 106 | } 107 | 108 | // This is the "message pump". Called by following functions: 109 | // win_getspeed(); 110 | // kbd_waitkey(); 111 | // 112 | // It is recommended to be called in any long loop where those two functions 113 | // are not called. 114 | 115 | void win_checkmessages(void) 116 | { 117 | SDL_Event event; 118 | unsigned keynum; 119 | 120 | win_activateclick = 0; 121 | 122 | SDL_PumpEvents(); 123 | 124 | while (SDL_PollEvent(&event)) 125 | { 126 | switch (event.type) 127 | { 128 | case SDL_JOYBUTTONDOWN: 129 | joybuttons[event.jbutton.which] |= 1 << event.jbutton.button; 130 | break; 131 | 132 | case SDL_JOYBUTTONUP: 133 | joybuttons[event.jbutton.which] &= ~(1 << event.jbutton.button); 134 | break; 135 | 136 | case SDL_JOYAXISMOTION: 137 | switch (event.jaxis.axis) 138 | { 139 | case 0: 140 | joyx[event.jaxis.which] = event.jaxis.value; 141 | break; 142 | 143 | case 1: 144 | joyy[event.jaxis.which] = event.jaxis.value; 145 | break; 146 | } 147 | break; 148 | 149 | case SDL_MOUSEMOTION: 150 | win_mousexpos = event.motion.x; 151 | win_mouseypos = event.motion.y; 152 | win_mousexrel += event.motion.xrel; 153 | win_mouseyrel += event.motion.yrel; 154 | break; 155 | 156 | case SDL_MOUSEBUTTONDOWN: 157 | switch(event.button.button) 158 | { 159 | case SDL_BUTTON_LEFT: 160 | win_mousebuttons |= MOUSEB_LEFT; 161 | break; 162 | 163 | case SDL_BUTTON_MIDDLE: 164 | win_mousebuttons |= MOUSEB_MIDDLE; 165 | break; 166 | 167 | case SDL_BUTTON_RIGHT: 168 | win_mousebuttons |= MOUSEB_RIGHT; 169 | break; 170 | } 171 | break; 172 | 173 | case SDL_MOUSEBUTTONUP: 174 | switch(event.button.button) 175 | { 176 | case SDL_BUTTON_LEFT: 177 | win_mousebuttons &= ~MOUSEB_LEFT; 178 | break; 179 | 180 | case SDL_BUTTON_MIDDLE: 181 | win_mousebuttons &= ~MOUSEB_MIDDLE; 182 | break; 183 | 184 | case SDL_BUTTON_RIGHT: 185 | win_mousebuttons &= ~MOUSEB_RIGHT; 186 | break; 187 | } 188 | break; 189 | 190 | case SDL_QUIT: 191 | win_quitted = 1; 192 | break; 193 | 194 | case SDL_KEYDOWN: 195 | win_virtualkey = event.key.keysym.sym; 196 | win_asciikey = event.key.keysym.unicode; 197 | keynum = event.key.keysym.sym & (MAX_KEYS-1); 198 | if (keynum < MAX_KEYS) 199 | { 200 | win_keytable[keynum] = 1; 201 | win_keystate[keynum] = 1; 202 | if ((keynum == KEY_ENTER) && ((win_keystate[KEY_ALT]) || (win_keystate[KEY_RIGHTALT]))) 203 | { 204 | win_fullscreen ^= 1; 205 | gfx_reinit(); 206 | } 207 | } 208 | break; 209 | 210 | case SDL_KEYUP: 211 | keynum = event.key.keysym.sym & (MAX_KEYS-1); 212 | if (keynum < MAX_KEYS) 213 | { 214 | win_keytable[keynum] = 0; 215 | win_keystate[keynum] = 0; 216 | } 217 | break; 218 | 219 | case SDL_VIDEORESIZE: 220 | case SDL_VIDEOEXPOSE: 221 | gfx_updatepage(); 222 | break; 223 | } 224 | } 225 | } 226 | 227 | void win_setmousemode(int mode) 228 | { 229 | win_mousemode = mode; 230 | 231 | switch(mode) 232 | { 233 | case MOUSE_ALWAYS_VISIBLE: 234 | SDL_ShowCursor(SDL_ENABLE); 235 | break; 236 | 237 | case MOUSE_FULLSCREEN_HIDDEN: 238 | if (gfx_fullscreen) 239 | { 240 | SDL_ShowCursor(SDL_DISABLE); 241 | } 242 | else 243 | { 244 | SDL_ShowCursor(SDL_ENABLE); 245 | } 246 | break; 247 | 248 | case MOUSE_ALWAYS_HIDDEN: 249 | SDL_ShowCursor(SDL_DISABLE); 250 | break; 251 | } 252 | } 253 | 254 | -------------------------------------------------------------------------------- /tools/bme_win.h: -------------------------------------------------------------------------------- 1 | // BME windows, input & timing module header file 2 | 3 | int win_openwindow(char *appname, char *icon); 4 | void win_closewindow(void); 5 | void win_messagebox(char *string); 6 | void win_checkmessages(void); 7 | int win_getspeed(int framerate); 8 | void win_setmousemode(int mode); 9 | 10 | extern int win_windowinitted; 11 | extern int win_windowactive; 12 | extern int win_quitted; 13 | extern int win_fullscreen; 14 | extern unsigned char win_keytable[MAX_KEYS]; 15 | extern unsigned char win_keystate[MAX_KEYS]; 16 | extern unsigned char win_asciikey; 17 | extern unsigned win_virtualkey; 18 | extern unsigned win_mousexpos; 19 | extern unsigned win_mouseypos; 20 | extern unsigned win_mousexrel; 21 | extern unsigned win_mouseyrel; 22 | extern unsigned win_mousebuttons; 23 | extern int win_mousemode; 24 | extern SDL_Joystick *joy[MAX_JOYSTICKS]; 25 | extern Sint16 joyx[MAX_JOYSTICKS]; 26 | extern Sint16 joyy[MAX_JOYSTICKS]; 27 | extern Uint32 joybuttons[MAX_JOYSTICKS]; 28 | 29 | -------------------------------------------------------------------------------- /tools/bmeconv.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cadaver/c64gameframework/15eaa821599c860ab94009085d6b340f93f65670/tools/bmeconv.exe -------------------------------------------------------------------------------- /tools/cp.bat: -------------------------------------------------------------------------------- 1 | copy *.exe c:\programs -------------------------------------------------------------------------------- /tools/dasm.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cadaver/c64gameframework/15eaa821599c860ab94009085d6b340f93f65670/tools/dasm.exe -------------------------------------------------------------------------------- /tools/dat2inc.c: -------------------------------------------------------------------------------- 1 | // 2 | // Datafile -> C include file 3 | // 4 | 5 | #include 6 | 7 | int main(int argc, char *argv[]) 8 | { 9 | FILE *in; 10 | FILE *out; 11 | int length; 12 | int c; 13 | 14 | if (argc < 3) 15 | { 16 | printf("Converts a binary datafile into a C include file\nUsage: dat2inc \n"); 17 | return 1; 18 | } 19 | in = fopen(argv[1], "rb"); 20 | if (!in) 21 | { 22 | printf("Datafile open error!\n"); 23 | return 1; 24 | } 25 | out = fopen(argv[2], "wt"); 26 | if (!out) 27 | { 28 | printf("Includefile open error!\n"); 29 | return 1; 30 | } 31 | fseek(in, 0, SEEK_END); 32 | length = ftell(in); 33 | fseek(in, 0, SEEK_SET); 34 | 35 | fprintf(out, "unsigned char datafile[] = {\n"); 36 | for (c = 0; c < length; c++) 37 | { 38 | if (c) 39 | { 40 | fprintf(out, ", "); 41 | if (!(c % 10)) fprintf(out, "\n"); 42 | } 43 | fprintf(out, "0x%02x", fgetc(in)); 44 | } 45 | fprintf(out, "};\n"); 46 | fclose(in); 47 | fclose(out); 48 | return 0; 49 | } 50 | 51 | -------------------------------------------------------------------------------- /tools/dat2inc.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cadaver/c64gameframework/15eaa821599c860ab94009085d6b340f93f65670/tools/dat2inc.exe -------------------------------------------------------------------------------- /tools/datafile.c: -------------------------------------------------------------------------------- 1 | // 2 | // Datafile creator 3 | // 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "fileio.h" 11 | 12 | #define MAXFILES 16384 13 | #define MAXFILENAME 64 14 | 15 | typedef struct 16 | { 17 | Uint32 offset; 18 | Uint32 length; 19 | char name[13]; 20 | } HEADER; 21 | 22 | static HEADER header[MAXFILES]; 23 | static char fullname[MAXFILES][MAXFILENAME]; 24 | static int files; 25 | 26 | int main(int argc, char **argv); 27 | int addfile(HEADER *header, FILE *dest, char *name); 28 | void fwrite8(FILE *file, unsigned data); 29 | void fwritele16(FILE *file, unsigned data); 30 | void fwritele32(FILE *file, unsigned data); 31 | 32 | int main(int argc, char **argv) 33 | { 34 | FILE *datafile, *listfile; 35 | int c; 36 | 37 | if (argc < 3) 38 | { 39 | printf("Combines files into a package for use with BME's datafile IO functions\nUsage: datafile \n"); 40 | return 0; 41 | } 42 | listfile = fopen(argv[2], "rt"); 43 | if (!listfile) 44 | { 45 | printf("ERROR: Couldn't open filelist.\n"); 46 | return 1; 47 | } 48 | datafile = fopen(argv[1], "wb"); 49 | if (!datafile) 50 | { 51 | printf("ERROR: Couldn't create datafile.\n"); 52 | fclose(listfile); 53 | return 1; 54 | } 55 | memset(&header[0], 0, MAXFILES * sizeof(HEADER)); 56 | // Get names from list 57 | for (;;) 58 | { 59 | char searchname[64]; 60 | int d; 61 | FILE *test; 62 | 63 | if (fscanf(listfile, "%63s", searchname) == EOF) break; 64 | test = fopen(searchname, "rb"); 65 | if (test) 66 | { 67 | fclose(test); 68 | 69 | strcpy(fullname[files], searchname); 70 | 71 | for (c = strlen(fullname[files]) - 1; c >= 0; c--) 72 | { 73 | if (fullname[files][c] == '\\') 74 | { 75 | c++; 76 | break; 77 | } 78 | } 79 | if (c < 0) c = 0; 80 | memset(header[files].name, 0, 13); 81 | d = 0; 82 | while (fullname[files][c]) 83 | { 84 | header[files].name[d] = toupper(fullname[files][c]); 85 | c++; 86 | d++; 87 | } 88 | files++; 89 | if (files == MAXFILES) break; 90 | } 91 | if (files == MAXFILES) break; 92 | } 93 | 94 | fclose(listfile); 95 | // Write datafile header 96 | fwrite("DAT!", 4, 1, datafile); 97 | fwritele32(datafile, files); 98 | // Write incomplete fileheaders 99 | for (c = 0; c < files; c++) 100 | { 101 | fwritele32(datafile, header[c].offset); 102 | fwritele32(datafile, header[c].length); 103 | fwrite(header[c].name, 13, 1, datafile); 104 | } 105 | // Process each file 106 | for (c = 0; c < files; c++) 107 | { 108 | printf("Adding %s...\n", header[c].name); 109 | if (!addfile(&header[c], datafile, fullname[c])) 110 | { 111 | printf("Terminating & deleting datafile...\n"); 112 | fclose(datafile); 113 | remove(argv[1]); 114 | return 1; 115 | } 116 | } 117 | // Seek back to start & write correct headers 118 | fseek(datafile, sizeof files + 4, SEEK_SET); 119 | for (c = 0; c < files; c++) 120 | { 121 | fwritele32(datafile, header[c].offset); 122 | fwritele32(datafile, header[c].length); 123 | fwrite(header[c].name, 13, 1, datafile); 124 | } 125 | fclose(datafile); 126 | printf("Everything OK!\n"); 127 | return 0; 128 | } 129 | 130 | int addfile(HEADER *header, FILE *dest, char *name) 131 | { 132 | FILE *src; 133 | unsigned char *originalbuf; 134 | 135 | src = fopen(name, "rb"); 136 | if (!src) 137 | { 138 | printf("ERROR: Couldn't open file %s\n", name); 139 | return 0; 140 | } 141 | header->offset = ftell(dest); 142 | fseek(src, 0, SEEK_END); 143 | header->length = ftell(src); 144 | fseek(src, 0, SEEK_SET); 145 | originalbuf = malloc(header->length); 146 | if (!originalbuf) 147 | { 148 | printf("ERROR: No memory to load file!\n"); 149 | fclose(src); 150 | return 0; 151 | } 152 | printf("* Loading file\n"); 153 | fread(originalbuf, header->length, 1, src); 154 | fclose(src); 155 | printf("* Writing file (size was %d)\n", header->length); 156 | fwrite(originalbuf, header->length, 1, dest); 157 | free(originalbuf); 158 | return 1; 159 | } 160 | -------------------------------------------------------------------------------- /tools/datafile.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cadaver/c64gameframework/15eaa821599c860ab94009085d6b340f93f65670/tools/datafile.exe -------------------------------------------------------------------------------- /tools/editfont.lbm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cadaver/c64gameframework/15eaa821599c860ab94009085d6b340f93f65670/tools/editfont.lbm -------------------------------------------------------------------------------- /tools/editfont.spr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cadaver/c64gameframework/15eaa821599c860ab94009085d6b340f93f65670/tools/editfont.spr -------------------------------------------------------------------------------- /tools/editio.h: -------------------------------------------------------------------------------- 1 | #ifdef __WIN32__ 2 | #include 3 | #include 4 | #include 5 | #else 6 | #include 7 | #include 8 | #include 9 | #define O_BINARY 0 10 | #endif 11 | 12 | unsigned char read8(int handle) 13 | { 14 | unsigned char bytes[1]; 15 | read(handle, bytes, 1); 16 | return bytes[0]; 17 | } 18 | 19 | unsigned short readle16(int handle) 20 | { 21 | unsigned char bytes[2]; 22 | read(handle, bytes, 2); 23 | return ((unsigned short)bytes[0]) | (((unsigned short)bytes[1]) << 8); 24 | } 25 | 26 | unsigned readle32(int handle) 27 | { 28 | unsigned char bytes[4]; 29 | read(handle, bytes, 4); 30 | return ((unsigned)bytes[0]) | (((unsigned)bytes[1]) << 8) | (((unsigned)bytes[2]) << 16) | (((unsigned)bytes[3]) << 24); 31 | } 32 | 33 | void write8(int handle, unsigned data) 34 | { 35 | unsigned char bytes[1]; 36 | 37 | bytes[0] = data; 38 | write(handle, bytes, 1); 39 | } 40 | 41 | void writele16(int handle, unsigned data) 42 | { 43 | unsigned char bytes[2]; 44 | 45 | bytes[0] = data; 46 | bytes[1] = data >> 8; 47 | write(handle, bytes, 2); 48 | } 49 | 50 | void writele32(int handle, unsigned data) 51 | { 52 | unsigned char bytes[4]; 53 | 54 | bytes[0] = data; 55 | bytes[1] = data >> 8; 56 | bytes[2] = data >> 16; 57 | bytes[3] = data >> 24; 58 | write(handle, bytes, 4); 59 | } 60 | -------------------------------------------------------------------------------- /tools/editor.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cadaver/c64gameframework/15eaa821599c860ab94009085d6b340f93f65670/tools/editor.dat -------------------------------------------------------------------------------- /tools/editor.lbm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cadaver/c64gameframework/15eaa821599c860ab94009085d6b340f93f65670/tools/editor.lbm -------------------------------------------------------------------------------- /tools/editor.pal: -------------------------------------------------------------------------------- 1 | ???"/2#,* '47$ / +;"6((( 99?" #)1 -------------------------------------------------------------------------------- /tools/editor.spr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cadaver/c64gameframework/15eaa821599c860ab94009085d6b340f93f65670/tools/editor.spr -------------------------------------------------------------------------------- /tools/exomizer3.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cadaver/c64gameframework/15eaa821599c860ab94009085d6b340f93f65670/tools/exomizer3.exe -------------------------------------------------------------------------------- /tools/fileio.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void fwrite8(FILE *file, unsigned data) 5 | { 6 | Uint8 bytes[1]; 7 | 8 | bytes[0] = data; 9 | fwrite(bytes, 1, 1, file); 10 | } 11 | 12 | void fwritele16(FILE *file, unsigned data) 13 | { 14 | Uint8 bytes[2]; 15 | 16 | bytes[0] = data; 17 | bytes[1] = data >> 8; 18 | fwrite(bytes, 2, 1, file); 19 | } 20 | 21 | void fwritele32(FILE *file, unsigned data) 22 | { 23 | Uint8 bytes[4]; 24 | 25 | bytes[0] = data; 26 | bytes[1] = data >> 8; 27 | bytes[2] = data >> 16; 28 | bytes[3] = data >> 24; 29 | fwrite(bytes, 4, 1, file); 30 | } 31 | 32 | unsigned fread8(FILE *file) 33 | { 34 | Uint8 bytes[1]; 35 | 36 | fread(bytes, 1, 1, file); 37 | return bytes[0]; 38 | } 39 | 40 | unsigned freadle16(FILE *file) 41 | { 42 | Uint8 bytes[2]; 43 | 44 | fread(bytes, 2, 1, file); 45 | return (bytes[0]) | (bytes[1] << 8); 46 | } 47 | 48 | unsigned freadle32(FILE *file) 49 | { 50 | Uint8 bytes[4]; 51 | 52 | fread(bytes, 4, 1, file); 53 | return (bytes[0]) | (bytes[1] << 8) | (bytes[2] << 16) | (bytes[3] << 24); 54 | } 55 | 56 | unsigned freadhe16(FILE *file) 57 | { 58 | Uint8 bytes[2]; 59 | 60 | fread(bytes, 2, 1, file); 61 | return (bytes[1]) | (bytes[0] << 8); 62 | } 63 | 64 | unsigned freadhe32(FILE *file) 65 | { 66 | Uint8 bytes[4]; 67 | 68 | fread(bytes, 4, 1, file); 69 | return (bytes[3]) | (bytes[2] << 8) | (bytes[1] << 16) | (bytes[0] << 24); 70 | } 71 | 72 | 73 | -------------------------------------------------------------------------------- /tools/fileio.h: -------------------------------------------------------------------------------- 1 | #ifndef FILEIO_H 2 | #define FILEIO_H 3 | 4 | void fwrite8(FILE *file, unsigned data); 5 | void fwritele16(FILE *file, unsigned data); 6 | void fwritele32(FILE *file, unsigned data); 7 | unsigned fread8(FILE *file); 8 | unsigned freadle16(FILE *file); 9 | unsigned freadle32(FILE *file); 10 | unsigned freadhe16(FILE *file); 11 | unsigned freadhe32(FILE *file); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /tools/filejoin.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main(int argc, char **argv) 6 | { 7 | FILE *in; 8 | FILE *out; 9 | unsigned c; 10 | char filename[80]; 11 | char *inbuffer; 12 | int length; 13 | 14 | if (argc < 3) 15 | { 16 | printf("Usage: filejoin +... \n"); 17 | return 1; 18 | } 19 | 20 | out = fopen(argv[2], "wb"); 21 | if (!out) 22 | { 23 | printf("Could not open output file %s\n", argv[2]); 24 | return 1; 25 | } 26 | 27 | memset(filename, 0, sizeof filename); 28 | for (c = 0; c < strlen(argv[1])+1; c++) 29 | { 30 | if ((argv[1][c] != '+') && (argv[1][c])) 31 | { 32 | filename[strlen(filename)] = argv[1][c]; 33 | } 34 | else 35 | { 36 | in = fopen(filename, "rb"); 37 | if (in) 38 | { 39 | fseek(in, 0, SEEK_END); 40 | length = ftell(in); 41 | fseek(in, 0, SEEK_SET); 42 | if (length) 43 | { 44 | inbuffer = malloc(length); 45 | if (!inbuffer) return 1; 46 | fread(inbuffer, length, 1, in); 47 | fwrite(inbuffer, length, 1, out); 48 | free(inbuffer); 49 | } 50 | fclose(in); 51 | memset(filename, 0, sizeof filename); 52 | } 53 | else 54 | { 55 | printf("Could not open input file %s\n", filename); 56 | fclose(out); 57 | return 1; 58 | } 59 | } 60 | } 61 | fclose(out); 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /tools/filejoin.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cadaver/c64gameframework/15eaa821599c860ab94009085d6b340f93f65670/tools/filejoin.exe -------------------------------------------------------------------------------- /tools/filelist.txt: -------------------------------------------------------------------------------- 1 | editor.spr 2 | editfont.spr 3 | editor.pal 4 | -------------------------------------------------------------------------------- /tools/filesplit.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main(int argc, char **argv) 6 | { 7 | FILE *in; 8 | FILE *out; 9 | unsigned c; 10 | char *inbuffer; 11 | int length; 12 | int startpos = 0; 13 | int splitlength = 0xffff; 14 | 15 | if (argc < 4) 16 | { 17 | printf("Usage: filesplit [length]\n"); 18 | return 1; 19 | } 20 | 21 | sscanf(argv[3], "%d", &startpos); 22 | if (argc > 4) 23 | sscanf(argv[4], "%d", &splitlength); 24 | 25 | in = fopen(argv[1], "rb"); 26 | if (in) 27 | { 28 | fseek(in, 0, SEEK_END); 29 | length = ftell(in); 30 | fseek(in, 0, SEEK_SET); 31 | if (length) 32 | { 33 | inbuffer = malloc(length); 34 | if (!inbuffer) return 1; 35 | fread(inbuffer, length, 1, in); 36 | if (startpos + splitlength > length) 37 | splitlength = length - startpos; 38 | out = fopen(argv[2], "wb"); 39 | if (!out) 40 | { 41 | printf("Could not open output file %s\n", argv[2]); 42 | free(inbuffer); 43 | fclose(in); 44 | return 1; 45 | } 46 | fwrite(&inbuffer[startpos], splitlength, 1, out); 47 | free(inbuffer); 48 | fclose(out); 49 | } 50 | fclose(in); 51 | } 52 | else 53 | { 54 | printf("Could not open input file %s\n", argv[1]); 55 | return 1; 56 | } 57 | 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /tools/filesplit.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cadaver/c64gameframework/15eaa821599c860ab94009085d6b340f93f65670/tools/filesplit.exe -------------------------------------------------------------------------------- /tools/gcommon.h: -------------------------------------------------------------------------------- 1 | #ifndef GCOMMON_H 2 | #define GCOMMON_H 3 | 4 | #define CMD_DONOTHING 0 5 | #define CMD_PORTAUP 1 6 | #define CMD_PORTADOWN 2 7 | #define CMD_TONEPORTA 3 8 | #define CMD_VIBRATO 4 9 | #define CMD_SETAD 5 10 | #define CMD_SETSR 6 11 | #define CMD_SETWAVE 7 12 | #define CMD_SETWAVEPTR 8 13 | #define CMD_SETPULSEPTR 9 14 | #define CMD_SETFILTERPTR 10 15 | #define CMD_SETFILTERCTRL 11 16 | #define CMD_SETFILTERCUTOFF 12 17 | #define CMD_SETMASTERVOL 13 18 | #define CMD_FUNKTEMPO 14 19 | #define CMD_SETTEMPO 15 20 | 21 | #define WTBL 0 22 | #define PTBL 1 23 | #define FTBL 2 24 | #define STBL 3 25 | 26 | #define MAX_FILT 64 27 | #define MAX_STR 32 28 | #define MAX_INSTR 64 29 | #define MAX_CHN 3 30 | #define MAX_PATT 208 31 | #define MAX_TABLES 4 32 | #define MAX_TABLELEN 255 33 | #define MAX_INSTRNAMELEN 16 34 | #define MAX_PATTROWS 128 35 | #define MAX_SONGLEN 254 36 | #define MAX_SONGS 32 37 | #define MAX_NOTES 96 38 | 39 | #define REPEAT 0xd0 40 | #define TRANSDOWN 0xe0 41 | #define TRANSUP 0xf0 42 | #define LOOPSONG 0xff 43 | 44 | #define ENDPATT 0xff 45 | #define INSTRCHG 0x00 46 | #define FX 0x40 47 | #define FXONLY 0x50 48 | #define FIRSTNOTE 0x60 49 | #define LASTNOTE 0xbc 50 | #define REST 0xbd 51 | #define KEYOFF 0xbe 52 | #define KEYON 0xbf 53 | #define OLDKEYOFF 0x5e 54 | #define OLDREST 0x5f 55 | 56 | #define WAVEDELAY 0x1 57 | #define WAVELASTDELAY 0xf 58 | #define WAVESILENT 0xe0 59 | #define WAVELASTSILENT 0xef 60 | #define WAVECMD 0xf0 61 | #define WAVELASTCMD 0xfe 62 | 63 | typedef struct 64 | { 65 | unsigned char ad; 66 | unsigned char sr; 67 | unsigned char ptr[MAX_TABLES]; 68 | unsigned char vibdelay; 69 | unsigned char gatetimer; 70 | unsigned char firstwave; 71 | unsigned char name[MAX_INSTRNAMELEN]; 72 | } INSTR; 73 | 74 | #endif 75 | 76 | -------------------------------------------------------------------------------- /tools/gfxconv.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cadaver/c64gameframework/15eaa821599c860ab94009085d6b340f93f65670/tools/gfxconv.exe -------------------------------------------------------------------------------- /tools/gt2mini.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cadaver/c64gameframework/15eaa821599c860ab94009085d6b340f93f65670/tools/gt2mini.exe -------------------------------------------------------------------------------- /tools/maked64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cadaver/c64gameframework/15eaa821599c860ab94009085d6b340f93f65670/tools/maked64.exe -------------------------------------------------------------------------------- /tools/makeef.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define MAXFILES 0x100 6 | #define FIRSTSAVEFILE 0xf0 7 | 8 | unsigned char* cart = new unsigned char[0x100000]; 9 | unsigned char* usedsectors = new unsigned char[0x1000]; 10 | int bootcodesize = 8192; 11 | int maxsize = 0; 12 | int savestartoffset = 0; 13 | int savefiles = 4; 14 | 15 | int getfreeoffset(int filesize) 16 | { 17 | int startsec = 0; 18 | 19 | int sectors = (filesize+0xff) / 0x100; 20 | 21 | for (int i = startsec; i < 0x1000; ++i) 22 | { 23 | for (int j = i; j < 0x1000; ++j) 24 | { 25 | if (usedsectors[j]) 26 | { 27 | i = j; 28 | break; 29 | } 30 | if (j - i == sectors-1) 31 | return i * 0x100; 32 | } 33 | } 34 | return -1; 35 | } 36 | 37 | void insertfile(unsigned char filenum, int startoffset, unsigned char* data, int filesize, bool leaveholes = false) 38 | { 39 | cart[0x0000+filenum] = ((startoffset >> 8) & 0x3f) + 0x80; // Startoffset within bank 40 | cart[0x0100+filenum] = (startoffset >> 14); // Bank 41 | cart[0x0200+filenum] = filesize & 0xff; 42 | cart[0x0300+filenum] = filesize >> 8; 43 | // If filesize lowbyte 0, must predecrement high size 44 | if (!(filesize & 0xff)) 45 | --cart[0x300+filenum]; 46 | 47 | memcpy(&cart[startoffset], data, filesize); 48 | int sectors = (filesize+0xff) >> 8; 49 | int startsec = startoffset >> 8; 50 | for (int i = startsec; i < sectors + startsec; ++i) 51 | { 52 | if (!leaveholes) 53 | usedsectors[i] = 1; 54 | else 55 | { 56 | // For the bootcode, we can leave holes in the allocation to fill it with data files later 57 | for (int j = 0; j < 256; ++j) 58 | { 59 | if (cart[i*256+j] != 0xff) 60 | { 61 | usedsectors[i] = 1; 62 | break; 63 | } 64 | } 65 | } 66 | } 67 | int fileend = startoffset+filesize; 68 | if (maxsize < fileend) 69 | { 70 | maxsize = fileend; 71 | maxsize = (maxsize+0x1ffff) & 0xfffe0000; 72 | } 73 | } 74 | 75 | int main(int argc, char **argv) 76 | { 77 | if (argc < 2) 78 | { 79 | printf("Usage: makeef [numsavefiles]\n" 80 | "Builds easyflash bin cartridge from bootcode (16KB) and sequencefile.\nEach savefile allocates 64KB from the cart, by default there's room for 4."); 81 | return 1; 82 | } 83 | 84 | if (argc > 4) 85 | { 86 | sscanf(argv[4], "%d", &savefiles); 87 | ++savefiles; 88 | savefiles &= 0xfe; 89 | } 90 | 91 | memset(cart, 0xff, 0x100000); 92 | memset(usedsectors, 0, 0x1000); 93 | // Mark the "directory" used 94 | for (int i = 0x00; i < 0x04; ++i) 95 | usedsectors[i] = 1; 96 | 97 | printf("Reading bootcode\n"); 98 | FILE* bootcode = fopen(argv[1], "rb"); 99 | if (!bootcode) 100 | { 101 | printf("Could not open bootcode\n"); 102 | return 1; 103 | } 104 | unsigned char* bootcodedata = new unsigned char[bootcodesize]; 105 | memset(bootcodedata, 0xff, bootcodesize); 106 | fread(bootcodedata, bootcodesize, 1, bootcode); 107 | fclose(bootcode); 108 | 109 | printf("Inserting bootcode\n"); 110 | insertfile(0xff, 0x4000-bootcodesize, bootcodedata, bootcodesize, true); 111 | delete[] bootcodedata; 112 | 113 | FILE* seqfile = fopen(argv[2], "rb"); 114 | if (!seqfile) 115 | { 116 | printf("Could not open sequence file\n"); 117 | return 1; 118 | } 119 | 120 | printf("Reading seqfile & inserting files\n"); 121 | char commandbuf[80]; 122 | while(fgets(commandbuf, 80, seqfile)) 123 | { 124 | char c64name[80]; 125 | char dosname[80]; 126 | int ret; 127 | 128 | ret = sscanf(commandbuf, "%s %s", &dosname[0], &c64name[0]); 129 | if (ret < 2) 130 | continue; 131 | if (dosname[0] == ';') 132 | continue; 133 | 134 | FILE *src; 135 | src = fopen((const char*)dosname, "rb"); 136 | if (!src) 137 | { 138 | printf("Could not open input file %s\n", dosname); 139 | return 1; 140 | } 141 | 142 | int filenum = strtol((const char*)c64name, 0, 16); 143 | fseek(src, 0, SEEK_END); 144 | int filesize = ftell(src); 145 | fseek(src, 0, SEEK_SET); 146 | if (filesize > 0 && filenum < FIRSTSAVEFILE) 147 | { 148 | unsigned char* filedata = new unsigned char[filesize]; 149 | fread(filedata, filesize, 1, src); 150 | fclose(src); 151 | int fileoffset = getfreeoffset(filesize); 152 | if (fileoffset < 0) 153 | { 154 | printf("Cart full\n"); 155 | return 1; 156 | } 157 | printf("File name %s number %d inserting to %d\n", dosname, filenum, fileoffset); 158 | insertfile(filenum, fileoffset, filedata, filesize); 159 | delete[] filedata; 160 | } 161 | else 162 | fclose(src); 163 | } 164 | 165 | savestartoffset = (maxsize + 0x1ffff) & 0xfffe0000; 166 | cart[0x03ff] = (savestartoffset >> 14); // Save start bank 167 | for (int i = 0; i < savefiles/2; ++i) 168 | { 169 | cart[savestartoffset + i * 0x20000 + 0] = 0; // Mark save directory itself invalid in directory to invalid to force EasyProg to erase the save bank on writing 170 | cart[savestartoffset + i * 0x20000 + 1] = 0; // Even files in low bank 171 | cart[savestartoffset + i * 0x20000 + 0x2000] = 0; 172 | cart[savestartoffset + i * 0x20000 + 0x2001] = 0; // Odd files in high bank 173 | } 174 | 175 | maxsize += savefiles * 0x10000; 176 | if (maxsize > 0x100000) 177 | { 178 | printf("Cart too large\n"); 179 | return 1; 180 | } 181 | 182 | FILE* out = fopen(argv[3], "wb"); 183 | if (!out) 184 | { 185 | printf("Could not open outfile\n"); 186 | return 1; 187 | } 188 | fwrite(cart, 0x100000, 1, out); 189 | fclose(out); 190 | printf("Cart image written, %d bytes\n", maxsize); 191 | return 0; 192 | } -------------------------------------------------------------------------------- /tools/makeef.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cadaver/c64gameframework/15eaa821599c860ab94009085d6b340f93f65670/tools/makeef.exe -------------------------------------------------------------------------------- /tools/makegmod2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define MAXFILES 0x100 6 | #define FIRSTSAVEFILE 0xf0 7 | 8 | unsigned char* cart = new unsigned char[0x80000]; 9 | unsigned char* usedsectors = new unsigned char[0x800]; 10 | int bootcodesize = 8192-MAXFILES*4; 11 | int maxsize = 0x80000; 12 | 13 | int getfreeoffset(int filesize) 14 | { 15 | int startsec = 0; 16 | 17 | int sectors = (filesize+0xff) / 0x100; 18 | 19 | for (int i = startsec; i < 0x800; ++i) 20 | { 21 | for (int j = i; j < 0x800; ++j) 22 | { 23 | if (usedsectors[j]) 24 | { 25 | i = j; 26 | break; 27 | } 28 | if (j - i == sectors-1) 29 | return i * 0x100; 30 | } 31 | } 32 | return -1; 33 | } 34 | 35 | void insertfile(unsigned char filenum, int startoffset, unsigned char* data, int filesize, bool leaveholes = false) 36 | { 37 | if (filenum < FIRSTSAVEFILE) 38 | { 39 | cart[0x1c00+filenum] = ((startoffset >> 8) & 0x1f) + 0x80; // Startoffset within bank 40 | cart[0x1d00+filenum] = (startoffset >> 13); // Bank 41 | cart[0x1e00+filenum] = filesize & 0xff; 42 | cart[0x1f00+filenum] = filesize >> 8; 43 | // If filesize lowbyte 0, must predecrement highbyte 44 | if (!(filesize & 0xff)) 45 | --cart[0x1f00+filenum]; 46 | } 47 | memcpy(&cart[startoffset], data, filesize); 48 | int sectors = (filesize+0xff) >> 8; 49 | int startsec = startoffset >> 8; 50 | for (int i = startsec; i < sectors + startsec; ++i) 51 | { 52 | if (!leaveholes) 53 | usedsectors[i] = 1; 54 | else 55 | { 56 | // For the bootcode, we can leave holes in the allocation to fill it with data files later 57 | for (int j = 0; j < 256; ++j) 58 | { 59 | if (cart[i*256+j] != 0xff) 60 | { 61 | usedsectors[i] = 1; 62 | break; 63 | } 64 | } 65 | } 66 | } 67 | int fileend = startoffset+filesize; 68 | } 69 | 70 | int main(int argc, char **argv) 71 | { 72 | if (argc < 4) 73 | { 74 | printf("Usage: makegmod2 \n" 75 | "Builds gmod2 bin cartridge from bootcode (8KB) and sequencefile."); 76 | return 1; 77 | } 78 | 79 | memset(cart, 0xff, 0x80000); 80 | memset(usedsectors, 0, 0x800); 81 | // Mark the "directory" used 82 | for (int i = 0x1c; i < 0x20; ++i) 83 | usedsectors[i] = 1; 84 | 85 | printf("Reading bootcode\n"); 86 | FILE* bootcode = fopen(argv[1], "rb"); 87 | if (!bootcode) 88 | { 89 | printf("Could not open bootcode\n"); 90 | return 1; 91 | } 92 | unsigned char* bootcodedata = new unsigned char[bootcodesize]; 93 | memset(bootcodedata, 0xff, bootcodesize); 94 | fread(bootcodedata, bootcodesize, 1, bootcode); 95 | fclose(bootcode); 96 | 97 | printf("Inserting bootcode\n"); 98 | insertfile(0xff, 0, bootcodedata, bootcodesize, true); 99 | delete[] bootcodedata; 100 | 101 | FILE* seqfile = fopen(argv[2], "rb"); 102 | if (!seqfile) 103 | { 104 | printf("Could not open sequence file\n"); 105 | return 1; 106 | } 107 | 108 | printf("Reading seqfile & inserting files\n"); 109 | char commandbuf[80]; 110 | while(fgets(commandbuf, 80, seqfile)) 111 | { 112 | char c64name[80]; 113 | char dosname[80]; 114 | int ret; 115 | 116 | ret = sscanf(commandbuf, "%s %s", &dosname[0], &c64name[0]); 117 | if (ret < 2) 118 | continue; 119 | if (dosname[0] == ';') 120 | continue; 121 | 122 | FILE *src; 123 | src = fopen((const char*)dosname, "rb"); 124 | if (!src) 125 | { 126 | printf("Could not open input file %s\n", dosname); 127 | return 1; 128 | } 129 | 130 | int filenum = strtol((const char*)c64name, 0, 16); 131 | fseek(src, 0, SEEK_END); 132 | int filesize = ftell(src); 133 | fseek(src, 0, SEEK_SET); 134 | if (filesize > 0 && filenum < FIRSTSAVEFILE) 135 | { 136 | unsigned char* filedata = new unsigned char[filesize]; 137 | fread(filedata, filesize, 1, src); 138 | fclose(src); 139 | int fileoffset = getfreeoffset(filesize); 140 | if (fileoffset < 0) 141 | { 142 | printf("Cart full\n"); 143 | return 1; 144 | } 145 | printf("File name %s number %d inserting to %d\n", dosname, filenum, fileoffset); 146 | insertfile(filenum, fileoffset, filedata, filesize); 147 | delete[] filedata; 148 | } 149 | else 150 | fclose(src); 151 | } 152 | 153 | FILE* out = fopen(argv[3], "wb"); 154 | if (!out) 155 | { 156 | printf("Could not open outfile\n"); 157 | return 1; 158 | } 159 | fwrite(cart, maxsize, 1, out); 160 | fclose(out); 161 | 162 | unsigned char eeprom[2048]; 163 | memset(eeprom, 0, sizeof eeprom); 164 | out = fopen(argv[4], "wb"); 165 | if (!out) 166 | { 167 | printf("Could not open outfile\n"); 168 | return 1; 169 | } 170 | fwrite(eeprom, 2048, 1, out); 171 | fclose(out); 172 | 173 | printf("Cart image written, %d bytes\n", maxsize); 174 | return 0; 175 | } -------------------------------------------------------------------------------- /tools/makegmod2.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cadaver/c64gameframework/15eaa821599c860ab94009085d6b340f93f65670/tools/makegmod2.exe -------------------------------------------------------------------------------- /tools/pack3.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main(int argc, char **argv) 6 | { 7 | char cmd[256]; 8 | if (argc < 3) 9 | { 10 | printf("Invokes exomizer3 raw mode with max.seq.length 256\nUsage: pack3 \n"); 11 | return 1; 12 | } 13 | 14 | sprintf(cmd, "exomizer3 raw -T4 -M256 -c -o%s %s", argv[2], argv[1]); 15 | return system(cmd); 16 | } 17 | -------------------------------------------------------------------------------- /tools/pack3.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cadaver/c64gameframework/15eaa821599c860ab94009085d6b340f93f65670/tools/pack3.exe -------------------------------------------------------------------------------- /tools/pchunk3.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char **argv) 5 | { 6 | char header[3]; 7 | int val; 8 | FILE *in; 9 | FILE *out; 10 | char cmd[256]; 11 | if (argc < 3) 12 | { 13 | printf("Invokes exomizer3 raw mode with max.seq.length 256, output with chunkfile header\nUsage: pchunk3 \n"); 14 | return 1; 15 | } 16 | in = fopen(argv[1], "rb"); 17 | if (!in) return 1; 18 | out = fopen("temp.bin", "wb"); 19 | if (!out) return 1; 20 | header[0] = fgetc(in); 21 | header[1] = fgetc(in); 22 | header[2] = fgetc(in); 23 | for(;;) 24 | { 25 | int c = fgetc(in); 26 | if (c == EOF) break; 27 | fputc(c, out); 28 | } 29 | fclose(in); 30 | fclose(out); 31 | 32 | sprintf(cmd, "exomizer3 raw -T4 -M256 -c -o%s %s", "temp2.bin", "temp.bin"); 33 | val = system(cmd); 34 | if (val > 0) return val; 35 | 36 | unlink("temp.bin"); 37 | in = fopen("temp2.bin", "rb"); 38 | if (!in) return 1; 39 | out = fopen(argv[2], "wb"); 40 | if (!out) return 1; 41 | fputc(header[0], out); 42 | fputc(header[1], out); 43 | fputc(header[2], out); 44 | for(;;) 45 | { 46 | int c = fgetc(in); 47 | if (c == EOF) break; 48 | fputc(c, out); 49 | } 50 | fclose(in); 51 | fclose(out); 52 | unlink("temp2.bin"); 53 | return val; 54 | } 55 | -------------------------------------------------------------------------------- /tools/pchunk3.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cadaver/c64gameframework/15eaa821599c860ab94009085d6b340f93f65670/tools/pchunk3.exe -------------------------------------------------------------------------------- /tools/spred3.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cadaver/c64gameframework/15eaa821599c860ab94009085d6b340f93f65670/tools/spred3.exe -------------------------------------------------------------------------------- /tools/stb_image_write.h: -------------------------------------------------------------------------------- 1 | /* stbiw-0.92 - public domain - http://nothings.org/stb/stb_image_write.h 2 | writes out PNG/BMP/TGA images to C stdio - Sean Barrett 2010 3 | no warranty implied; use at your own risk 4 | 5 | 6 | Before including, 7 | 8 | #define STB_IMAGE_WRITE_IMPLEMENTATION 9 | 10 | in the file that you want to have the implementation. 11 | 12 | 13 | ABOUT: 14 | 15 | This header file is a library for writing images to C stdio. It could be 16 | adapted to write to memory or a general streaming interface; let me know. 17 | 18 | The PNG output is not optimal; it is 20-50% larger than the file 19 | written by a decent optimizing implementation. This library is designed 20 | for source code compactness and simplicitly, not optimal image file size 21 | or run-time performance. 22 | 23 | USAGE: 24 | 25 | There are three functions, one for each image file format: 26 | 27 | int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes); 28 | int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data); 29 | int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data); 30 | 31 | Each function returns 0 on failure and non-0 on success. 32 | 33 | The functions create an image file defined by the parameters. The image 34 | is a rectangle of pixels stored from left-to-right, top-to-bottom. 35 | Each pixel contains 'comp' channels of data stored interleaved with 8-bits 36 | per channel, in the following order: 1=Y, 2=YA, 3=RGB, 4=RGBA. (Y is 37 | monochrome color.) The rectangle is 'w' pixels wide and 'h' pixels tall. 38 | The *data pointer points to the first byte of the top-left-most pixel. 39 | For PNG, "stride_in_bytes" is the distance in bytes from the first byte of 40 | a row of pixels to the first byte of the next row of pixels. 41 | 42 | PNG creates output files with the same number of components as the input. 43 | The BMP and TGA formats expand Y to RGB in the file format. BMP does not 44 | output alpha. 45 | 46 | PNG supports writing rectangles of data even when the bytes storing rows of 47 | data are not consecutive in memory (e.g. sub-rectangles of a larger image), 48 | by supplying the stride between the beginning of adjacent rows. The other 49 | formats do not. (Thus you cannot write a native-format BMP through the BMP 50 | writer, both because it is in BGR order and because it may have padding 51 | at the end of the line.) 52 | */ 53 | 54 | #ifndef INCLUDE_STB_IMAGE_WRITE_H 55 | #define INCLUDE_STB_IMAGE_WRITE_H 56 | 57 | #ifdef __cplusplus 58 | extern "C" { 59 | #endif 60 | 61 | extern int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes); 62 | extern int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data); 63 | extern int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data); 64 | 65 | #ifdef __cplusplus 66 | } 67 | #endif 68 | 69 | #endif//INCLUDE_STB_IMAGE_WRITE_H 70 | -------------------------------------------------------------------------------- /tools/symbols.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define MAXLISTSYMBOLS 16384 6 | 7 | char *symbol[MAXLISTSYMBOLS]; 8 | 9 | int main(int argc, char **argv) 10 | { 11 | FILE *in = NULL; 12 | FILE *out = NULL; 13 | FILE *list = NULL; 14 | char buffer[80]; 15 | char name[80]; 16 | int address; 17 | int c, d; 18 | if (argc < 2) 19 | { 20 | printf("Usage: symbols [outfile] [list]\n" 21 | "If list-file is not specified, will output all symbols.\n" 22 | "If out-file is not specified, only analyzes the symbols.\n"); 23 | return 1; 24 | } 25 | 26 | in = fopen(argv[1], "rt"); 27 | if (!in) 28 | { 29 | printf("Error opening input file!\n"); 30 | return 1; 31 | } 32 | 33 | if (argc > 2) 34 | { 35 | out = fopen(argv[2], "wt"); 36 | if (!out) 37 | { 38 | printf("Error opening output file!\n"); 39 | return 1; 40 | } 41 | } 42 | 43 | if (argc > 3) 44 | { 45 | list = fopen(argv[3], "rt"); 46 | if (list) 47 | { 48 | for (c = 0; c < MAXLISTSYMBOLS-1; c++) 49 | { 50 | if (!fgets(buffer, 80, list)) break; 51 | if (strlen(buffer)) 52 | { 53 | char *sptr = buffer; 54 | while (*sptr) 55 | { 56 | if (*sptr == 13) *sptr = 0; 57 | if (*sptr == 10) *sptr = 0; 58 | sptr++; 59 | } 60 | symbol[c] = strdup(buffer); 61 | } 62 | else break; 63 | } 64 | symbol[c] = NULL; 65 | fclose(list); 66 | } 67 | } 68 | 69 | int numsymbols = 0; 70 | char* symbols[MAXLISTSYMBOLS]; 71 | int addresses[MAXLISTSYMBOLS]; 72 | int pos = 0; 73 | 74 | if (out) 75 | { 76 | while (fgets(buffer, 80, in)) 77 | { 78 | int nameok = 1; 79 | 80 | sscanf(buffer, "%s %x", &name[0], &address); 81 | for (c = 0; c < strlen(name); c++) 82 | { 83 | if (name[c] == '.') nameok = 0; // Don't dump macro labels 84 | } 85 | if (!strcmp(name, "---")) nameok = 0; // Newer DASM symbol file title, skip 86 | 87 | if (nameok) 88 | { 89 | if (list) 90 | { 91 | for (c = 0;; c++) 92 | { 93 | if (!symbol[c]) break; 94 | if (!strcmp(symbol[c], name)) 95 | { 96 | fprintf(out, "%s = $%04x\n", name, address); 97 | break; 98 | } 99 | } 100 | } 101 | else 102 | { 103 | for (pos = 0; pos < numsymbols; pos++) 104 | { 105 | if (addresses[pos] > address) 106 | break; 107 | } 108 | 109 | for (c = numsymbols - 1; c >= pos; c--) 110 | { 111 | symbols[c+1] = symbols[c]; 112 | addresses[c+1] = addresses[c]; 113 | } 114 | symbols[pos] = strdup(name); 115 | addresses[pos] = address; 116 | numsymbols++; 117 | } 118 | } 119 | } 120 | 121 | // If no list of symbols, print everything sorted by address 122 | if (!list) 123 | { 124 | for (c = 0; c < numsymbols; ++c) 125 | { 126 | fprintf(out, "%s = $%04x\n", symbols[c], addresses[c]); 127 | } 128 | } 129 | 130 | fclose(out); 131 | } 132 | else 133 | { 134 | // Pagecross analyze-mode 135 | while (fgets(buffer, 80, in)) 136 | { 137 | int nameok = 1; 138 | 139 | address = -1; 140 | sscanf(buffer, "%s %x", &name[0], &address); 141 | if (address == -1) 142 | sscanf(buffer, "%s = $%x", &name[0], &address); 143 | 144 | for (c = 0; c < strlen(name); c++) 145 | { 146 | if (name[c] == '.') 147 | { 148 | nameok = 0; // Don't use macro labels 149 | break; 150 | } 151 | } 152 | // In Hessian / Steel Ranger code labels begin with uppercase; these can be ignored in pagecross analyze 153 | if (isupper(name[0])) 154 | nameok = 0; 155 | if (!nameok) 156 | continue; 157 | 158 | for (pos = 0; pos < numsymbols; pos++) 159 | { 160 | if (addresses[pos] > address) 161 | break; 162 | } 163 | 164 | for (c = numsymbols - 1; c >= pos; c--) 165 | { 166 | symbols[c+1] = symbols[c]; 167 | addresses[c+1] = addresses[c]; 168 | } 169 | symbols[pos] = strdup(name); 170 | addresses[pos] = address; 171 | numsymbols++; 172 | } 173 | 174 | for (c = 0; c < numsymbols; c++) 175 | { 176 | printf("%s = $%04x", symbols[c], addresses[c]); 177 | if (c < numsymbols - 1) 178 | { 179 | if ((addresses[c+1] - addresses[c] <= 0x100) && addresses[c] >= 0x200) 180 | { 181 | if ((addresses[c] & 0xff00) != ((addresses[c+1]-1) & 0xff00)) 182 | printf(" (PAGE CROSS)"); 183 | } 184 | } 185 | printf("\n"); 186 | } 187 | } 188 | 189 | fclose(in); 190 | 191 | return 0; 192 | } 193 | -------------------------------------------------------------------------------- /tools/symbols.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cadaver/c64gameframework/15eaa821599c860ab94009085d6b340f93f65670/tools/symbols.exe -------------------------------------------------------------------------------- /tools/usecount.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | struct Symbol 9 | { 10 | std::string name; 11 | int address; 12 | int count = 0; 13 | }; 14 | 15 | bool comparesymbol(const Symbol& lhs, const Symbol& rhs) 16 | { 17 | return lhs.count > rhs.count; 18 | } 19 | 20 | int main(int argc, char **argv) 21 | { 22 | if (argc < 2) 23 | { 24 | printf("Usage: usecount \n" 25 | "Scans the current directory for .s files and shows sorted use count for symbols\n"); 26 | return 1; 27 | } 28 | 29 | FILE* in = fopen(argv[1], "rt"); 30 | if (!in) 31 | { 32 | printf("Error opening symbol file\n"); 33 | return 1; 34 | } 35 | 36 | char buffer[80]; 37 | std::vector symbols; 38 | std::map codeLabels; 39 | 40 | printf("Reading symbols\n"); 41 | while (fgets(buffer, 80, in)) 42 | { 43 | Symbol newsymbol; 44 | char name[80]; 45 | sscanf(buffer, "%s %x", &name[0], &newsymbol.address); 46 | newsymbol.name = name; 47 | 48 | if (newsymbol.name == "---") 49 | continue; // Newer DASM symbol file title, skip 50 | 51 | for (int c = 0; c < newsymbol.name.length(); c++) 52 | { 53 | if (newsymbol.name[c] == '.') 54 | continue; // Don't dump macro labels 55 | } 56 | 57 | // In Hessian / Steel Ranger code labels begin with uppercase; these can be ignored 58 | if (isupper(newsymbol.name[0])) 59 | codeLabels[newsymbol.name] = false; 60 | else 61 | symbols.push_back(newsymbol); 62 | } 63 | fclose(in); 64 | 65 | std::vector filenames; 66 | DIR* dir = opendir("."); 67 | if (dir) 68 | { 69 | struct dirent *ent; 70 | while (ent = readdir(dir)) 71 | { 72 | std::string name = ent->d_name; 73 | if (name.find(".s") != std::string::npos) 74 | filenames.push_back(name); 75 | } 76 | closedir(dir); 77 | } 78 | 79 | for (int c = 0; c < filenames.size(); ++c) 80 | { 81 | if (filenames[c] == argv[1]) 82 | continue; // Skip the symbol file itself 83 | FILE* in = fopen(filenames[c].c_str(), "rt"); 84 | if (in) 85 | { 86 | printf("Examining file %s\n", filenames[c].c_str()); 87 | 88 | while (fgets(buffer, 80, in)) 89 | { 90 | std::string line(buffer); 91 | for (int d = 0; d < symbols.size(); ++d) 92 | { 93 | int pos = line.find(symbols[d].name); 94 | int endpos = pos + symbols[d].name.length(); 95 | if (pos != 0 && pos != std::string::npos && line[pos-1] == ' ' && (endpos == line.length() || (!isalpha(line[endpos]) && !isdigit(line[endpos])))) 96 | { 97 | ++symbols[d].count; 98 | break; 99 | } 100 | } 101 | for (std::map::iterator i = codeLabels.begin(); i != codeLabels.end(); ++i) 102 | { 103 | int pos = line.find(i->first); 104 | if (pos != 0 && pos != std::string::npos) 105 | i->second = true; 106 | } 107 | } 108 | fclose(in); 109 | } 110 | } 111 | 112 | std::sort(symbols.begin(), symbols.end(), comparesymbol); 113 | for (int c = 0; c < symbols.size(); ++c) 114 | printf("Symbol %s uses %d\n", symbols[c].name.c_str(), symbols[c].count); 115 | for (std::map::const_iterator i = codeLabels.begin(); i != codeLabels.end(); ++i) 116 | { 117 | if (!i->second) 118 | printf("Unused code symbol %s\n", i->first.c_str()); 119 | } 120 | 121 | return 0; 122 | } -------------------------------------------------------------------------------- /tools/usecount.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cadaver/c64gameframework/15eaa821599c860ab94009085d6b340f93f65670/tools/usecount.exe -------------------------------------------------------------------------------- /tools/worlded3.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cadaver/c64gameframework/15eaa821599c860ab94009085d6b340f93f65670/tools/worlded3.exe --------------------------------------------------------------------------------