-#ifndef GFX_H_
-#define GFX_H_
-
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
+#include "gfx.h"
#include "vbe.h"
-#include "dpmi.h"
-#include "logger.h"
+#include "cdpmi.h"
+
+#ifdef __DJGPP__
+#include <sys/nearptr.h>
+#define REALPTR(s, o) (void*)(((uint32_t)(s) << 4) - __djgpp_base_address + (uint32_t)(o))
+#else
#define REALPTR(s, o) (void*)(((uint32_t)(s) << 4) + (uint32_t)(o))
+#endif
+
#define VBEPTR(x) REALPTR(((x) & 0xffff0000) >> 16, (x) & 0xffff)
#define VBEPTR_SEG(x) (((x) & 0xffff0000) >> 16)
#define VBEPTR_OFF(x) ((x) & 0xffff)
#define SAME_BPP(a, b) \
- ((a) == (b) || (a) == 16 && (b) == 15 || (a) == 15 && (b) == 16 || (a) == 32 && (b) == 24 || (a) == 24 && (b) == 32)
+ ((a) == (b) || ((a) == 16 && (b) == 15) || ((a) == 15 && (b) == 16) || \
+ ((a) == 32 && (b) == 24) || ((a) == 24 && (b) == 32))
static unsigned int make_mask(int sz, int pos);
static struct vbe_mode_info *mode_info;
static int pal_bits = 6;
+static void *vpgaddr[2];
+
+
void *set_video_mode(int xsz, int ysz, int bpp)
{
int i;
- uint16_t *modes, best = 0;
- unsigned int fbsize;
+ static uint16_t *modes;
+ uint16_t best = 0;
+ unsigned int fbsize, pgsize;
+
+#ifdef __DJGPP__
+ __djgpp_nearptr_enable();
+#endif
/* check for VBE2 support and output some info */
if(!vbe_info) {
return 0;
}
- printlog("VBE Version: %x.%x\n", vbe_info->version >> 8, vbe_info->version & 0xff);
+ printf("VBE Version: %x.%x\n", vbe_info->version >> 8, vbe_info->version & 0xff);
if(vbe_info->version < 0x200) {
fprintf(stderr, "This program requires VBE 2.0 or greater. Try running UniVBE\n");
return 0;
}
- printlog("Graphics adapter: %s, %s (%s)\n", VBEPTR(vbe_info->oem_vendor_name_ptr),
- VBEPTR(vbe_info->oem_product_name_ptr), VBEPTR(vbe_info->oem_product_rev_ptr));
- printlog("Video memory: %dkb\n", vbe_info->total_mem << 6);
+ printf("Graphics adapter: %s, %s (%s)\n", (char*)VBEPTR(vbe_info->oem_vendor_name_ptr),
+ (char*)VBEPTR(vbe_info->oem_product_name_ptr), (char*)VBEPTR(vbe_info->oem_product_rev_ptr));
+ printf("Video memory: %dkb\n", vbe_info->total_mem << 6);
modes = VBEPTR(vbe_info->vid_mode_ptr);
}
/* attempt to set 8 bits of color per component in palettized modes */
/*if(bpp <= 8) {
pal_bits = vbe_set_palette_bits(8);
- printlog("palette bits per color primary: %d\n", pal_bits);
+ printf("palette bits per color primary: %d\n", pal_bits);
}
*/
- fbsize = xsz * ysz * mode_info->num_img_pages * (bpp / CHAR_BIT);
- return (void*)dpmi_mmap(mode_info->fb_addr, fbsize);
+ printf("avail video pages: %d\n", mode_info->num_img_pages);
+ printf("bytes per scanline: %d (%d pixels)\n", vbe_get_scanlen(VBE_SCANLEN_BYTES),
+ vbe_get_scanlen(VBE_SCANLEN_PIXELS));
+
+ pgsize = xsz * ysz * (bpp / CHAR_BIT);
+ fbsize = mode_info->num_img_pages * pgsize;
+ vpgaddr[0] = (void*)dpmi_mmap(mode_info->fb_addr, fbsize);
+
+ if(mode_info->num_img_pages > 1) {
+ vpgaddr[1] = (char*)vpgaddr[0] + pgsize;
+ } else {
+ vpgaddr[1] = 0;
+ }
+ return vpgaddr[0];
}
int set_text_mode(void)
vbe_set_palette(idx, col, 1, pal_bits);
}
-void wait_vsync(void)
+void *page_flip(int vsync)
{
- __asm {
- mov dx, 0x3da
- l1:
- in al, dx
- and al, 0x8
- jnz l1
- l2:
- in al, dx
- and al, 0x8
- jz l2
+ static int frame;
+ void *nextaddr;
+ int y, when, bufidx;
+
+ if(!vpgaddr[1]) {
+ /* page flipping not supported */
+ return 0;
+ }
+
+ bufidx = ++frame & 1;
+
+ y = bufidx ? mode_info->yres : 0;
+ nextaddr = vpgaddr[bufidx];
+
+ when = vsync ? VBE_SET_DISP_START_VBLANK : VBE_SET_DISP_START_NOW;
+ if(vbe_set_disp_start(0, y, when) == -1) {
+ return 0;
+ }
+
+ if(vsync == FLIP_VBLANK_WAIT) {
+ wait_vsync();
}
+ return nextaddr;
}
static unsigned int make_mask(int sz, int pos)
}
return mask << pos;
}
-
-
-#endif /* GFX_H_ */