Image Map Image Map
Page 2 of 16 FirstFirst 12345612 ... LastLast
Results 11 to 20 of 151

Thread: VGA & CGA Graphics Library for DOS Games

  1. #11
    Join Date
    Dec 2014
    Location
    The Netherlands
    Posts
    1,455

    Default

    I am in two minds about this.
    Something 'like SDL or Allegro' is not what I'm interested in personally, since they are relatively high-level, and mainly allow you to manipulate (linear) framebuffers.
    To get things fast on 8088/CGA, you generally need to do special trickery, which would probably break generic routines.
    So I wouldn't want to go as far as having an entire 'framework' which sets up the videomode for you and manages the framebuffer (and even keyboard and other input).

    Having said that, I am working on my own asm and C headers and helper functions, aimed more at doing this special trickery. This is more in the form of simple macros and such to perform low-level things, like inserting an unrolled loop to poll for hsync or such. Or to put the PIC in auto-EOI mode, or reprogramming the PIT etc.

    I also think that preprocessing tools may be useful. Eg, for 8088 MPH I wrote some some tools to convert any image (JPG, PNG, GIF, whatever) to an assembly listing in CGA, EGA or VGA memory layout. And of course the sprite compiler, which outputs an assembly listing with routines to draw and erase sprites.
    Having such a tool, in source form, would be useful, because you can easily expand it for custom tricks.

    Likewise, having line drawing routines, blitters etc in source/macro form would also be useful. They give you a basis you can adapt for any custom videomode or other tricks you can think of. But I think having a fixed library/framework is an abstraction level too high for efficient 8088 code.

  2. #12

    Default

    Hi,

    Quote Originally Posted by neilobremski View Post
    Do you have a schedule in mind? Is there a game/demo you want to make using this to show off its capabilities? And finally, what are your target languages and compilers? (I'm assuming 16-bit C compilers and entry-points)
    No, I don't have a schedule in mind. I would like to make a game to show what its capable of doing, I don't think it would be efficient enough to create demos. And I'm using Borland C 3.1.

    Quote Originally Posted by PgrAm View Post
    a 320x200 256 color bmp is 64k. if the image only has 16 colors it can be encoded as a 4 bit image and be only 32k.

    If you need code for Mode X, I have written a bunch of routines for that. Including loading a 4 bit BMP onto 4 planes.
    Cool, can I use that to load 4 bit BMP on VGA mode 13h? because I'm still having trouble with that one...

    Quote Originally Posted by Chuck(G) View Post
    Have you looked at MEWEL? (A goodie from the old days)
    Whats MEWEL? I can't Google it because it similar to "NEWELL" which is a famous football team here, so if I try to googe it all I get are pages related to that team.

    Quote Originally Posted by reenigne View Post
    I took a quick look at your code, and noticed a bug. If you use putimage_clip and clipping does actually happen, then width will no longer be the same as the stride of the source image, so it won't display correctly. You need to separate the stride (a property of the data being displayed) with the width (a property of the putimage operation in question). It'd be nice if it clipped against the left and top of the screen as well (which implies check_boundaries being able to adjust the source data pointer).
    I'll see if I can fix that

    Quote Originally Posted by reenigne View Post
    The code seems fairly well optimized, but I can suggest a couple of improvements for putimage. If you can arrange to use "rep movsw" instead of "rep movsb" you may be able to get a little extra speed boost. Of course, if you have an odd number of bytes to write you'll have to do an extra movsb, and testing for that on each line would likely negate the advantage on all but the widest sprites. A nice feature for a speed-oriented graphics library would be the ability to "compile" a sprite into a piece of code that plots that sprite as quickly as possible (perhaps expanding that "rep movsw" into a sequence of movsw opcodes optionally followed by a movsb). This is even more interesting for CGA, when you might have 2, 4 or 8 different bit patterns depending on the low bits of the horizontal position. Another improvement: instead of having both "mov di, bx" and "add bx, 320" in the y loop, you can set bx to 320-width outside of the loop and then just do "add di, bx" inside the loop. Similarly, rather than loading cx from width (in memory) each row, you could put width in ax outside the loop and do "mov cx, ax" inside the loop.
    Is this what you mean?

    Code:
    void putimage(int x, int y, int width, int height, unsigned char *src)
    {
    	asm push ds
    	asm mov ax, VGA_VID_SEG
    	asm mov es, ax
    	asm mov ax, 320
    	asm mul y
    	asm add ax, x
    	asm mov bx, ax        // ES:BX = A000:[320 * Y + X]
    	asm cld
    	asm lds si, src       // DS:SI = OFFSET [src]
    	asm mov dx, height
    _draw_line:
    	asm mov di, bx
    	asm mov cx, width
    	asm rep movsb         // ES:DI <- DS:SI Put byte on screen
    	asm add bx, 320       // Next line
    	asm dec dx            // Decrease height counter
    	asm jnz _draw_line
    	asm pop ds
    }
    Quote Originally Posted by reenigne View Post
    What other graphics primitives are you thinking of adding? Bresenham lines? Filled triangles? Outline and filled ellipses? Gradients? Scaling and rotation? Text plotting? 3D transformations and texture mapping? There are a lot of possible rabbit holes to go down, depending on how much time you want to spend on it! And of course there are other modes and adapters as well (EGA, PCjr, Hercules).
    I'm not very interested in those things, I was thinking about adding sprite animations, also keyboard and sound too.

    What do you guys mean by "compile sprites"?

  3. #13
    Join Date
    Mar 2011
    Location
    Atlanta, GA, USA
    Posts
    904

    Default

    Quote Originally Posted by NicolasF View Post
    What do you guys mean by "compile sprites"?
    Sprite compilers take a bitmap - usually with a transparent key color - and generate a series of binary opcodes that comprise a function to draw the bitmap/sprite into a frame buffer at a parameterized line-stepping. The opcodes are usually the initial register setup and a lot of mov reg, immediates and mov framebuffer,reg instructions. That way when you want to draw the sprite over an over, you have a perfectly optimized draw function for that image and you don't have to use a traditional blit function that checks height*width number of pixels for alpha key and moves src->dst accordingly.

    Sprite compilers can be done at compile time with static images or more often done at run time during a game start-up phase where all the draw functions are compiled based on run time parameters like video mode, resolution, etc.

    They were specially big in parallax engines where you had to composite a lot of sprites at a high frame rate on low end hardware.
    Last edited by eeguru; February 8th, 2017 at 07:44 AM.
    "Good engineers keep thick authoritative books on their shelf. Not for their own reference, but to throw at people who ask stupid questions; hoping a small fragment of knowledge will osmotically transfer with each cranial impact." - Me

  4. #14
    Join Date
    Dec 2014
    Location
    The Netherlands
    Posts
    1,455

    Default

    I've attached the compiled sprite for the DeLorean from 8088 MPH, so you can get an idea.
    The compiler generated 8 routines in total:
    doDelorean00, doDelorean01, doDelorean10, doDelorean11
    doRestoreDelorean00, doRestoreDelorean01, doRestoreDelorean10, doRestoreDelorean11

    The first 4 are for rendering the sprite to the frontbuffer. There are 4 versions, because in the 160x200 16-colour mode used, there are 2 pixels packed into a byte. This means that if you want pixel-perfect horizontal placement, you need two versions of the sprite, one starting on an even x-coord, another for an odd x-coord.
    Likewise, in the y-direction you also need 2 variations. Namely, the video mode used has an interleaved layout in memory. The even and odd scanlines are each stored in separate banks. So when you want to move from an even to an odd scanline, you need a different relative offset from when you want to move from an odd to an even scanline. So in total you need 2*2 = 4 variations to have pixel-perfect placement in both directions.
    With some simple logic you pick the right variation to call for the position you want to draw the sprite at.

    The compiler is designed to compile the sprites in memory-order. This means that it first does all even scanlines, then all odd scanlines (or vice-versa). This means that you require smaller displacements from scanline to scanline, leading to more compact and efficient code.

    The second set of 4 routines is the same approach in terms of X and Y positioning. They however erase the sprite by replacing it with pixels from the background image. These routines are 'coarse' in that they round to entire bytes, rather than doing the pixel-perfect masking that the sprite routine does. It is more efficient to just replace entire bytes or words with the background image, than to try and restore individual pixels.

    As you can see, the compiler tries to optimize for various different cases, sometimes processing bytes, sometimes words. Sometimes using immediate operands, sometimes using movsw or movsb to copy from memory.
    It also uses inc si/inc di for small updates, or groups them together in a single add for larger displacements.
    And when masking, it knows that it only needs the and/or sequence when it needs to or non-zero bytes or words. Else it just performs the and, and skips the or, which would be a nop anyway.
    So you could say it is a real (optimizing) compiler.
    This allowed the large DeLorean to fly over the screen at 60 fps.

    If you google for example code, you often just find some simple 'template' with mov instructions, where only immediate operands are replaced with the pixel data by the 'compiler'. That is still highly inefficient, because these are very large and slow instructions.
    Attached Files Attached Files
    Last edited by Scali; February 8th, 2017 at 06:51 AM.

  5. #15

    Default

    Quote Originally Posted by NicolasF View Post
    Is this what you mean?
    Not quite. I was thinking more along the lines of:

    Code:
    void putimage(int x, int y, int width, int height, unsigned char *src)
    {
    	asm push ds
    	asm mov ax, VGA_VID_SEG
    	asm mov es, ax
    	asm mov ax, 320
    	asm mul y
    	asm add ax, x
    	asm mov bx, ax        // ES:BX = A000:[320 * Y + X]
    	asm cld
    	asm lds si, src       // DS:SI = OFFSET [src]
    	asm mov dx, height
    	asm mov bx, 320
    	asm mov ax, width
    	asm sub bx, ax
    	asm shr ax, 1
    	asm jc _odd_width
    _draw_line:
    	asm mov cx, ax
    	asm rep movsw         // ES:DI <- DS:SI Put byte on screen
    	asm add di, bx        // Next line
    	asm dec dx            // Decrease height counter
    	asm jnz _draw_line
    	asm pop ds
    	asm jmp _done
    _odd_width:
    	asm mov cx, ax
    	asm rep movsw
    	asm movsb
    	asm add di, bx
    	asm dec dx
    	asm jnz _odd_width
    	asm pop ds
    _done:
    }

  6. #16
    Join Date
    Sep 2011
    Location
    Toronto, Canada
    Posts
    150

    Default

    Quote Originally Posted by NicolasF View Post
    Cool, can I use that to load 4 bit BMP on VGA mode 13h? because I'm still having trouble with that one...
    With some modification, Yes. I'll modify the code to work with 1 plane then I can send that to you. basically you have to read two pixels at a time and use bit-masks to separate them, 4 bit bmps are always padded to width multiples of two so this is easy.
    Last edited by PgrAm; February 8th, 2017 at 10:21 AM.
    Currently working on new DOS game, Chuck Jones: Space Cop of the Future, Check out my Dev Blog

    Vintage Computers:
    Unitron Apple II clone, 2x Commodore Vic-20, Commodore 64, Commodore 128, Amiga 500, Macintosh Plus, Macintosh SE, 3 386sx PCs, Atari TT030

  7. #17
    Join Date
    Aug 2006
    Location
    Chicagoland, Illinois, USA
    Posts
    4,026
    Blog Entries
    1

    Default

    To directly answer the OP's question: There are already libraries and a lot of already-optimized code you can either directly use or borrow for your own library. Some of the more efficient code for graphics are contained in the following books:

    - Programmer's Guide to PC & PS/2 Video Systems, Richard Wilton, Microsoft Press. ISBN 1-55615-103-9. Covers the basics of CGA through VGA.

    - Programmer's Guide to the EGA and VGA Cards by Richard F Ferraro. The bible for EGA/VGA tweaking.

    - Zen of Graphics Programming by Michael Abrash (Note this is NOT the same book as "Graphics Programming Black Book" which came later and removed a lot of the EGA/VGA basics). This covers EGA and later in less detail than Ferraro's book, but what it does cover is explained very well (latching, in particular).

    There are several VGA libraries writte in C, including many that cover "mode-x". Looking around Garbo, x2ftp, and Simtel mirrors will turn up a lot of them. Unlike Allegro, many of them don't require 386 instructions or protected mode. http://ftp.lanet.lv/ftp/mirror/x2ftp...s/00index.html in particular might have everything you need. You may also want to look up xlibpas by Tristan Tarrant, as it compiled the best of the best mode-x routines into a single lib. It's technically Pascal, but 99% of the code is inline assembler so that is easy to rip out and repurpose.

    The FastGraph library is still available if you'd rather not code anything at all; the demo can still be downloaded and is fully functional, although you make all calls through a loaded TSR and it displays a message on exit, so not ideal.

    I was thinking about adding sprite animations, also keyboard and sound too.

    If that's the case, you might as well use Allegro 4.2 and be done with it. Allegro already supports what you're trying to do, as long as you only care about VGA.


    Last edited by Trixter; February 8th, 2017 at 10:31 AM.
    Offering a bounty for:
    - Music Construction Set, IBM Music Feature edition (has red sticker on front stating IBM Music Feature)
    - Any very old/ugly IBM joystick (such as the Franklin JS-123)

  8. #18

    Default

    Quote Originally Posted by Trixter View Post
    If that's the case, you might as well use Allegro 4.2 and be done with it. Allegro already supports what you're trying to do, as long as you only care about VGA.
    NicolasF specifically mentioned wanting to support 8088 machines, though. Allegro (at least since version 2) requires DJGPP, so will only work on 32-bit machines.

  9. #19

    Default

    Just adding a philosophical couple of cents: build the library.

    You'll be happier having done so yourself rather than copying someone else's and it will give you a full understanding of why you would/will use someone else's library. I fully endorse building first and then studying later to cover the holes you missed in your knowledge.

    No one has ever developed the perfect code library ... so maybe you'll be the first.

  10. #20
    Join Date
    Aug 2006
    Location
    Chicagoland, Illinois, USA
    Posts
    4,026
    Blog Entries
    1

    Default

    I made the assumption that 386+ wasn't going to be an issue because he started with VGA first, and MCGA 320x200 256-color mode is not appropriate for anything requiring speed on an 8088 due to how much memory you're slinging around.

    I agree making your own library is the most fun, but isn't always the most practical. When he said he wanted to start throwing in input handling and sound (the latter of which is not easy to tackle for a beginner), I figured why reinvent the wheel?
    Offering a bounty for:
    - Music Construction Set, IBM Music Feature edition (has red sticker on front stating IBM Music Feature)
    - Any very old/ugly IBM joystick (such as the Franklin JS-123)

Page 2 of 16 FirstFirst 12345612 ... LastLast

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •