VOGONS

Common searches


First post, by keenmaster486

User metadata
Rank l33t
Rank
l33t

I wanted to challenge myself and I'm in a take-it-on mood right now so here we go...

This thread will document my endeavors to create a 2D scrolling platformer game on both DOS and Web platforms before Wednesday.

This is for a class I am taking. I'll have the entire time from now until then to do nothing but work on this project non-stop. The Web version is the actual deliverable for the class so I'll be doing it first.

I'm doing this because I want a challenge, I want to motivate myself to learn DOS real mode programming, and because the Web version of the game is going to be easy enough that I can finish it in about a day with little issue.

Here's the link to the Web version which you can use to see my progress on that side of it if you are interested:
https://github.com/keenmaster486/sei-game-pro … aster/README.md
It'll be using Javascript and the HTML canvas element to draw things. No real need for high efficiency because modern computers are so freaking fast 😵

The DOS version will be 16-bit, real mode, developed in Open Watcom. VGA Mode 13h, Adlib music (if I get to it).

The two version will share graphics and level data.

I'll post updates as I go along.

Right now I have some basic VGA drawing code for the DOS version, and some experimentation with HTML canvas for the web version. By the end of today I want to have the Web version mostly done if not all done.

Wish me luck. Now it's time to get in the zone.

World's foremost 486 enjoyer.

Reply 1 of 4, by konc

User metadata
Rank l33t
Rank
l33t

The DOS game won't happen before Wednesday.
(I wish you all the best for your assignment and I'm honestly just challenging you and making fun on this since you posted it here on vogons, not playing it smart 🤣 )

Reply 2 of 4, by keenmaster486

User metadata
Rank l33t
Rank
l33t
konc wrote:

The DOS game won't happen before Wednesday.
(I wish you all the best for your assignment and I'm honestly just challenging you and making fun on this since you posted it here on vogons, not playing it smart )

You were right!

Just for the lolz, I ended up adding features to the Web version that are actually really difficult to implement in DOS without using Mode X. I wrote a bunch of Mode 13h routines which work great, but there's no way I'm doing full-screen parallax scrolling without using Mode X, and I'll need a lot longer than a week to learn that.

So just the web version for now - http://keenmaster486.github.io/sei-game-project
And the code and description/instructions here: http://github.com/keenmaster486/sei-game-project

World's foremost 486 enjoyer.

Reply 3 of 4, by beastlike

User metadata
Rank Member
Rank
Member

In looking at some old code, I found some files that I must've downloaded from a BBS or FTP site back in the day;

this is not the same as what I have, but some quoted google searches took me to some similar stuff, what I had was an earlier version of this:
https://bos.asmhackers.net/docs/vga_without_b … pet_1/modsrc30/

plus I have this putsprite:
------------------------------------------------------------------------------------------------------------------------------------------------
putsprite proc near
push cx dx di ; save registers
mov ax, dx
shl ax, 6 ; y*64
shl dx, 4 ; y*16
add ax, dx ; y*80
mov dx, cx
shr dx, 2 ; divide by 4 (4 planes)
add ax, dx ; add to offset
mov di, ax ; put in dest index
and cl, 3 ; x MOD 4
mov dx, SC_INDEX ; address map mask
mov al, 2 ; plane enable
mov ah, 1 ; hi byte=plane number
shl ah, cl
mov bx, ax
out dx, ax ; out to map mask
mov dx, 4
xloop:
mov cx, 16
push si di
yloop:
mov eax, ds:[si]
mov es:[di], eax
add si, 16
add di, 80
loop yloop
pop di si
add si, 4
push dx
mov dx, SC_INDEX
mov ax, bx
rol ah, 1
cmp ah, 10000b
jnz nores
mov ah, 1
inc di
nores:
mov bx, ax
out dx, ax
pop dx
dec dx
jg xloop
pop di dx cx ; retore used regs
ret
putsprite endp

and this, it doesn't look like my code, I'm pretty sure I grabbed it from somewhere, but I forget where. you'll have to forgive me it's been at least 20 years:
------------------------------------------------------------------------------------------------------------
.model small
.stack 200h
.386

SC_INDEX equ 03c4h ;Sequence Controller Index
CRTC_INDEX equ 03d4h ;CRT Controller Index
MAP_MASK equ 2
READ_MAP equ 4
MISC_OUTPUT equ 03c2h ;Miscellaneous Output register
SCREEN_SEG equ 0a000h ;segment of display memory in mode X
DAC_INDEX equ 03c8h ;DAC registers
GC_INDEX equ 03ceh ;Graphics controller

.data

CRTParms label word
dw 00d06h ;vertical total
dw 03e07h ;overflow (bit 8 of vertical counts)
dw 04109h ;cell height (2 to double-scan)
dw 0ea10h ;v sync start
dw 0ac11h ;v sync end and protect cr0-cr7
dw 0df12h ;vertical displayed
dw 00014h ;turn off dword mode
dw 0e715h ;v blank start
dw 00616h ;v blank end
dw 0e317h ;turn on byte mode
CRT_PARM_LENGTH equ (($-CRTParms)/2)

.code

; *********************** PROCEDURES ***************************

;------------------- Set Mode X ----------------------
;***PRE-LOAD:
; cx = horizontal width of virtual screen ( in steps of 8 )
; ie 320 (1 screen) requires a pre-load of 40

setmodex PROC NEAR
mov ax, 13h
int 10h
mov cx, 40
mov dx, SC_INDEX ;Sequencer Address register
mov ax, 0604h ;Index 4, unset bit 3
out dx, ax ;disable Chain 4

mov dx, CRTC_INDEX
mov al, 13h ;mode 13..chain4 dimensions
out dx, al
inc dx ;port 03d5..where we set the size
mov al, cl ;screen width / 8
out dx, al

mov dx, CRTC_INDEX
mov ax, 0014h ;disableing doubleword mode
out dx, ax

;enableing byte mode
mov ax, 0E317h
out dx, ax
ret
setmodex ENDP

fillscreen proc near
;clear a full unchained screen
mov cx, ax
mov dx, 03c4h ;Map mask register
mov al, 2
out dx, al
inc dx
mov al, 1111b ;ALL planes
out dx, al

mov ax, 0A000h
mov es, ax
xor di, di
mov ax, cx
mov cx, 32768
mov ah, al
rep stosw ;put zeros 1 word at a time
ret
fillscreen endp

public _fillscreen, _putpixel, _getpixel, _setx, _hline, _vline, _box
public _kbhit, _getkey

_getkey proc near
mov ah, 7
int 21h
ret
_getkey endp

_kbhit proc near
mov ah, 0Bh
int 21h
ret
_kbhit endp

_fillscreen PROC NEAR
push bp
mov bp, sp
push di
mov ax, [bp+4]
call fillscreen
pop di bp
ret
_fillscreen ENDP

video dw 0A000h
lmasks db 1111b, 1110b, 1100b, 1000b
rmasks db 0001b, 0011b, 0111b, 1111b

_hline proc near
mov es, video
push bp
mov bp, sp
push cx dx si di ; save registers
mov cx, [bp+4]
mov dx, [bp+6]
mov si, [bp+8]
mov ax, [bp+10]
mov ah, al
push ax
mov ax, dx
shl ax, 6 ; y*64
shl dx, 4 ; y*16
add ax, dx ; y*80
mov dx, cx
shr dx, 2 ; divide by 4 (4 planes)
add ax, dx ; add to offset
mov di, ax ; put in dest index
mov dx, 03c4h ;Map mask register
mov al, 2
out dx, al
inc dx
and cl, 3
mov bx, cx
xor bh, bh
mov al, lmasks[bx]
out dx, al
pop bx
mov ax, bx
stosb
mov al, 1111b
out dx, al
mov ax, bx
mov si, [bp+8]
mov cx, [bp+4]
shr cx, 2
shr si, 2
sub si, cx
mov cx, si
dec cx
shr cx, 1
rep stosw
adc cx, 0
rep stosb
mov cx, [bp+8]
and cl, 3
push bx
mov bx, cx
xor bh, bh
mov al, rmasks[bx]
out dx, al
pop ax
mov es:[di], al
pop di si dx cx bp ; retore used regs
ret
_hline endp

vl dw 0

_box proc near
mov es, video
push bp
mov bp, sp
push cx dx si di ; save registers
mov cx, [bp+4]
mov dx, [bp+6]
mov si, [bp+8]
mov ax, [bp+12]
mov ah, al
push ax
mov ax, dx
shl ax, 6 ; y*64
shl dx, 4 ; y*16
add ax, dx ; y*80
mov dx, cx
shr dx, 2 ; divide by 4 (4 planes)
add ax, dx ; add to offset
mov di, ax ; put in dest index
mov dx, 03c4h ;Map mask register
mov al, 2
out dx, al
inc dx
and cl, 3
mov bx, cx
xor bh, bh
mov al, lmasks[bx]
out dx, al
pop bx
mov ax, bx
push di
mov cx, [bp+10]
sub cx, [bp+6]
mov vl, cx
yloop1:
stosb
add di, 79
loop yloop1
pop di
inc di
mov al, 1111b
out dx, al
mov ax, bx
mov cx, [bp+4]
shr cx, 2
shr si, 2
sub si, cx
dec si
push bx dx di
mov dx, vl
mov bx, 80
sub bx, si
yloop2:
mov cx, si
shr cx, 1
rep stosw
adc cx, 0
rep stosb
add di, bx
dec dx
jg yloop2
pop di dx bx
inc di
mov cx, [bp+8]
and cl, 3
push bx
mov bx, cx
xor bh, bh
mov al, rmasks[bx]
out dx, al
pop ax
mov cx, vl
add di, si
dec di
yloop3:
mov es:[di], al
add di, 80
loop yloop3
pop di si dx cx bp ; retore used regs
ret
_box endp

set320x240 PROC NEAR
mov dx,SC_INDEX
mov ax,0100h
out dx,ax ;synchronous reset while switching clocks

; mov dx, MISC_OUTPUT
; mov ax, 2c11h
; out dx, ax ;turn off write protect

mov dx,MISC_OUTPUT
mov al,0e3h
out dx,al ;select 28 MHz dot clock & 60 Hz scanning rate

mov dx,SC_INDEX
mov ax,0300h
out dx,ax ;undo reset (restart sequencer)

mov dx,CRTC_INDEX ;reprogram the CRT Controller
mov al,11h ;VSync End reg contains register write
out dx,al ; protect bit
inc dx ;CRT Controller Data register
in al,dx ;get current VSync End register setting
and al,7fh ;remove write protect on various
out dx,al ; CRTC registers
dec dx ;CRT Controller Index
cld
mov ax, @data
mov ds, ax
mov si,offset CRTParms ;point to CRT parameter table
mov cx,CRT_PARM_LENGTH ;# of table entries
SetCRTParmsLoop:
lodsw ;get the next CRT Index/Data pair
out dx,ax ;set the next CRT Index/Data pair
loop SetCRTParmsLoop

comment *

mov dx, 3D4h
mov al, 9
out dx, al
inc dx
in al, dx
and al, not 1fh
out dx,al
dec dx
mov al,14h
out dx,al
inc dx
in al,dx
and al, not 40h
out dx,al
dec dx
mov al,17h
out dx,al
inc dx
in al,dx
or al,40h
out dx,al
*
ret
set320x240 ENDP

_setx proc near
push ds bp
call setmodex
;call set320x240
mov ax, 0
call fillscreen
pop bp ds
ret
_setx endp

_putpixel proc near
mov es, video
push bp
mov bp, sp
push cx dx di ; save registers
mov cx, [bp+4]
mov dx, [bp+6]
mov ax, [bp+8]
push ax
mov ax, dx
shl ax, 6 ; y*64
shl dx, 4 ; y*16
add ax, dx ; y*80
mov dx, cx
shr dx, 2 ; divide by 4 (4 planes)
add ax, dx ; add to offset
mov di, ax ; put in dest index
and cl, 3 ; x MOD 4
mov dx, SC_INDEX ; address map mask
mov al, MAP_MASK ; plane enable
mov ah, 1 ; hi byte=plane number
shl ah, cl
out dx, ax ; out to map mask
pop ax ; restore color
mov es:[di], al ; write color to video mem
pop di dx cx bp ; retore used regs
ret
_putpixel endp

_vline proc near
mov es, video
push bp
mov bp, sp
push cx dx di ; save registers
mov cx, [bp+4]
mov dx, [bp+6]
mov ax, [bp+10]
push ax
mov ax, dx
shl ax, 6 ; y*64
shl dx, 4 ; y*16
add ax, dx ; y*80
mov dx, cx
shr dx, 2 ; divide by 4 (4 planes)
add ax, dx ; add to offset
mov di, ax ; put in dest index
and cl, 3 ; x MOD 4
mov dx, SC_INDEX ; address map mask
mov al, MAP_MASK ; plane enable
mov ah, 1 ; hi byte=plane number
shl ah, cl
out dx, ax ; out to map mask
pop ax ; restore color
mov cx, [bp+8]
sub cx, [bp+6]
yvloop:
mov es:[di], al ; write color to video mem
add di, 80
loop yvloop
pop di dx cx bp ; retore used regs
ret
_vline endp

_getpixel proc near
mov es, video
push bp
mov bp, sp
mov cx, [bp+4]
mov dx, [bp+6]
push cx dx di ; save registers
mov ax, dx
shl ax, 6 ; y*64
shl dx, 4 ; y*16
add ax, dx ; y*80
mov dx, cx
shr dx, 2 ; divide by 4 (4 planes)
add ax, dx ; add to offset
mov di, ax ; put in dest index
mov dx, GC_INDEX ; address map mask
mov al, READ_MAP ; plane enable
mov ah, cl ; hi byte=plane number
and ah, 3
out dx, ax ; out to map mask
mov al, es:[di] ; read color from video mem
pop di dx cx bp ; retore used regs
ret
_getpixel endp

end
------------------------------------------------------------------------------------------------------------

Mike Abrash's Zen of Graphics Programming has some stuff on Mode X, the PDF version can be found out there on the internet

Also, PCGPE (Programmers Game Programming something-or-other) had some resources on ModeX - here's one of the files, you can probably find more copies out there - https://www.pcorner.com/list/UPLOAD/PCGPE.ZIP/MODEX.TXT/

Good luck! Would love to test

Reply 4 of 4, by spiroyster

User metadata
Rank Oldbie
Rank
Oldbie

Using FF 66.03 (Windows 10). There is a savage leak somewhere? Gets a bit laggy after a while, but this might be FF struggling to consume enough mem each cycle 😉. I got ~95000 points (approx 15 secs) before it hung on me.

Capture.PNG
Filename
Capture.PNG
File size
3.35 KiB
Views
281 views
File license
Fair use/fair dealing exception

Might struggle to get that working on a DOS machine? Good start though, nice to see it stay quite true to concept image.