Rocksolid Light

Welcome to novaBBS (click a section below)

mail  files  register  nodelist  faq  login

A year spent in artificial intelligence is enough to make one believe in God.


programming / alt.lang.asm / Re: Wiering's Mario/TP w/ inline asm, convert to Delphi?? (was: Re: Video: Skynet ? on Pentium 166 from 1997 ?)

Subject: Re: Wiering's Mario/TP w/ inline asm, convert to Delphi?? (was: Re: Video: Skynet ? on Pentium 166 from 1997 ?)
From: skybuck2...@hotmail.com
Newsgroups: alt.lang.asm
Date: Tue, 4 Feb 2020 04:41 UTC
References: 1 2
X-Received: by 2002:a37:674d:: with SMTP id b74mr27881948qkc.396.1580791301089;
Mon, 03 Feb 2020 20:41:41 -0800 (PST)
X-Received: by 2002:a25:b31b:: with SMTP id l27mr21698866ybj.58.1580791300885;
Mon, 03 Feb 2020 20:41:40 -0800 (PST)
Path: i2pn2.org!i2pn.org!aioe.org!peer01.am4!peer.am4.highwinds-media.com!peer03.iad!feed-me.highwinds-media.com!news.highwinds-media.com!news-out.google.com!nntp.google.com!postnews.google.com!google-groups.googlegroups.com!not-for-mail
Newsgroups: alt.lang.asm
Date: Mon, 3 Feb 2020 20:41:40 -0800 (PST)
In-Reply-To: <af04b01d-e600-4cde-a763-543e7b805cc2@googlegroups.com>
Complaints-To: groups-abuse@google.com
Injection-Info: google-groups.googlegroups.com; posting-host=84.25.116.141; posting-account=np6u_wkAAADxbE7UBGUIOm-csir6aX02
NNTP-Posting-Host: 84.25.116.141
References: <d38a277f-1671-46a2-a712-84a8127644ab@googlegroups.com> <af04b01d-e600-4cde-a763-543e7b805cc2@googlegroups.com>
User-Agent: G2/1.0
MIME-Version: 1.0
Message-ID: <ddf0fda1-246d-4f91-868a-7548a8a9f336@googlegroups.com>
Subject: Re: Wiering's Mario/TP w/ inline asm, convert to Delphi?? (was: Re:
Video: Skynet ? on Pentium 166 from 1997 ?)
From: skybuck2...@hotmail.com
Injection-Date: Tue, 04 Feb 2020 04:41:41 +0000
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
X-Received-Bytes: 9054
X-Received-Body-CRC: 1056217231
View all headers
The most important routine is probably DrawImage:

Going to investigate further how the scrolling is done, but might be build into draw image, not sure yet, or maybe via x-mode scrolling dont know yet investigating by disabling things in tp7 ;)

Hello,

Now that I have a turbo pascal IDE working in MS-DOS 6.22 in VMWare I can experiment with mario clone source code (mike wieringa) and can confirm that the following assembler routine is very important, it is responsible for drawing all the sprites/bitmaps, except background shades or so:

Now I already tried and convert it myself a little bit, but I think I missed to include some variables.

Anyway if any of you assembler experts could convert this to pascal then that would be awesome and help any conversion for sure:

(I will include my own down below so you could expand on that)

// Including all variables/constants used just in case:

  const
    VGA_SEGMENT           = $A000;

    WINDOWHEIGHT        = 13 * 14;
    WINDOWWIDTH         = 16 * 20;

    SCREEN_WIDTH        = 320;
    SCREEN_HEIGHT       = 200;

    VIR_SCREEN_WIDTH    = SCREEN_WIDTH + 2 * 20;
    VIR_SCREEN_HEIGHT   = 182;
    BYTES_PER_LINE      = VIR_SCREEN_WIDTH div 4;

    MISC_OUTPUT         = $03C2;
    SC_INDEX            = $03C4;
    GC_INDEX            = $03CE;
    CRTC_INDEX          = $03D4;
    VERT_RESCAN         = $03DA;

    MAP_MASK            = 2;
    MEMORY_MODE         = 4;

    VERT_RETRACE_MASK   = 8;

    MAX_SCAN_LINE       = 9;
    START_ADDRESS_HIGH  = $C;
    START_ADDRESS_LOW   = $D;
    UNDERLINE           = $14;
    MODE_CONTROL        = $17;

    READ_MAP            = 4;
    GRAPHICS_MODE       = 5;
    MISCELLANEOUS       = 6;

    MAX_SCREENS         = 24;
    MAX_PAGE            = 1;
    PAGE_SIZE           = (VIR_SCREEN_HEIGHT + MAX_SCREENS) * BYTES_PER_LINE;
    PAGE_0              = 0;
    PAGE_1              = $8000;

    YBASE               = 9;


  const
    InGraphicsMode: Boolean = FALSE;

// implementation

  var
    OldExitProc: Pointer;
    OldScreenMode: Byte;

  const
    XView: Integer = 0;
    YView: Integer = 0;

    Page: Integer = 0;
    PageOffset: Word = 0;

    YOffset: Integer = 0;

    SAFE = 34 * BYTES_PER_LINE;

    Stack: array[0..MAX_PAGE] of Word       (PAGE_0 + PAGE_SIZE + SAFE,
       PAGE_1 + PAGE_SIZE + SAFE);


  procedure DrawImage (XPos, YPos, Width, Height: Integer; var BitMap);
    { Draw an image on the screen (NULL-bytes are ignored) }
  begin
    asm
        push    ds

        mov     ax, VGA_SEGMENT
        mov     es, ax

        mov     ax, YPos
        cmp     ax, VIR_SCREEN_HEIGHT
        jb      @NotNeg
        jg      @End
        mov     bx, ax
        add     bx, Height
        jnc     @End
  @NotNeg:
        mov     bx, BYTES_PER_LINE
        mul     bx
        mov     di, XPos
        mov     bx, di
        shr     di, 1
        shr     di, 1
        add     di, ax                  { DI = (YPos * 80) + XPos / 4 }
        add     di, PageOffset

        lds     si, BitMap              { Point to bitmap }

        and     bl, 3
        mov     cl, bl
        mov     ah, 1
        shl     ah, cl
        sub     bl, 4
        mov     cx, 4                   { 4 planes }

  @Plane:
        push    bx
        push    cx                      { Planes to go }
        push    ax                      { Mask in AH }

        mov     al, MAP_MASK
        mov     dx, SC_INDEX
        out     dx, ax

        cld
        push    di
        mov     bx, Width
        shr     bx, 1
        shr     bx, 1
        mov     ax, BYTES_PER_LINE
        sub     ax, bx                  { Space before next line }
        mov     dx, Height
  @Line:
        mov     cx, bx
        shr     cx, 1

        push    ax
        pushf

  @Pixel:
        lodsw
        or      al, al
        jz      @Skip1
        seges
        mov     [di], al
  @Skip1:
        inc     di
        or      ah, ah
        jz      @Skip2
        seges
        mov     [di], ah
  @Skip2:
        inc     di
        loop    @Pixel

        popf
        rcl     cx, 1
        jcxz    @Skip3

        lodsb
        or      al, al
        jz      @Odd
        stosb
        jmp     @Skip3
  @Odd: inc     di
  @Skip3:
        pop     ax
        add     di, ax
        dec     dx
        jnz     @Line

        pop     di

        pop     ax
        mov     al, ah
        mov     cl, 4
        shl     al, cl
        or      ah, al                  { Mask for next byte }
        rol     ah, 1                   { Bit mask for next plane }
        pop     cx                      { Planes }
        pop     bx
        inc     bl                      { Still in the same byte? }
        adc     di, 0
        loop    @Plane

    @End:
        pop     ds
    end;
  end;


My conversion so far (probably so palette loading code missing, but gives some idea what this does):

type

TWindowsPixel = packed record
case integer of
0 : (Value : integer );
1 : (Blue,Green,Red,Alpha : byte);
end;

TWindowsPixelBuffer = packed record
case integer of
0 : (Lixel : array[0..64000-1] of TWindowsPixel);
1 : (Pixel : array[0..199,0..319] of TWindowsPixel);
end;

TVGAPixel = byte;

TVGAPixelBuffer = packed record
case integer of
0 : (Lixel : array[0..64000-1] of TVGAPixel);
1 : (Pixel : array[0..199,0..319] of TVGAPixel);
end;

TVGAPaletteEntry = record
Red, Green, Blue : byte;
end;

TVGAPalette = array[0..255] of TVGAPaletteEntry;

var
InGraphicsMode: Boolean = FALSE;

// Buffer : array[0..(320*200)-1] of integer;
// PixelBuffer : array[0..199,0..319] of integer;


WindowsBuffer : array[0..1] of TWindowsPixelBuffer;

VGAPalette : TVGAPalette;
VGABuffer : TVGAPixelBuffer;


function GetBitmapPixel( x,y,width,height : integer; var BitMap ) : TVGAPixel;
var
BytePtr : ^Byte;
begin
// result := byte( Pointer( Integer( Bitmap ) + 2 + (Y * Width) + X )^ );

BytePtr := pointer(bitmap);

if BytePtr = nil then exit;

inc(BytePtr); // skips over width
  inc(BytePtr); // skips over height
  inc(BytePtr, y * width );
inc(BytePtr, x );

result := BytePtr^;

// result := byte( pointer( longword(Bitmap) + 2 + (Y * Width) + X )^ );
end;

procedure DrawImage(XPos, YPos, Width, Height: Integer; var BitMap);
{ Draw an image on the screen (NULL-bytes are ignored) }
var
VGAPixel : integer;
bx,by : integer; // bitmap x,y
px,py : integer; // pixel x,y
begin
for by:= 0 to Height-1 do
begin
py := ypos + by;
// py := py mod 200;
if (py >= 0) and (py<200) then
for bx:= 0 to Width-1 do
begin
px := xpos + bx;
// px := px mod 320;
if (px >= 0) and (px < 320) then
begin
VGAPixel := GetBitmapPixel(bx,by,width,height,pointer(@bitmap)^);
// VGABuffer.Pixel[py,px] := GetBitmapPixel(bx,by,width,height,bitmap);


WindowsBuffer[CurrentPage].Pixel[py,px].Red := P256[VGAPixel,0] * 4;
WindowsBuffer[CurrentPage].Pixel[py,px].Green := P256[VGAPixel,1] * 4;
WindowsBuffer[CurrentPage].Pixel[py,px].Blue := P256[VGAPixel,2] * 4;
// WindowsBuffer.Pixel[py,px].Red := P256[GetBitmapPixel(bx,by,width,height,bitmap),0];
// WindowsBuffer.Pixel[py,px].Red := P256[GetBitmapPixel(bx,by,width,height,bitmap),0];
end;
end;
end;

end;

Bye for now,
  Skybuck.


SubjectRepliesAuthor
o Video: Skynet ? on Pentium 166 from 1997 ?

By: skybuck2000 on Tue, 31 Dec 2019

8skybuck2000
rocksolid light 0.7.2
clearneti2ptor