kopia lustrzana https://github.com/Jean-MarcHarvengt/MCUME
				
				
				
			
		
			
				
	
	
		
			469 wiersze
		
	
	
		
			10 KiB
		
	
	
	
		
			C
		
	
	
			
		
		
	
	
			469 wiersze
		
	
	
		
			10 KiB
		
	
	
	
		
			C
		
	
	
 | 
						|
/*
 | 
						|
 *   O2EM Freeware Odyssey2 / Videopac+ Emulator
 | 
						|
 *
 | 
						|
 *   Created by Daniel Boris <dboris@comcast.net>  (c) 1997,1998
 | 
						|
 *
 | 
						|
 *   Developed by Andre de la Rocha <adlroc@users.sourceforge.net>
 | 
						|
 *
 | 
						|
 *   http://o2em.sourceforge.net
 | 
						|
 *
 | 
						|
 *
 | 
						|
 *
 | 
						|
 *   O2 Video Display Controller emulation
 | 
						|
 */
 | 
						|
 | 
						|
 | 
						|
#include <stdlib.h>
 | 
						|
#include <string.h>
 | 
						|
#include <stdio.h>
 | 
						|
#include "types.h"
 | 
						|
#include "vmachine.h"
 | 
						|
#include "config.h"
 | 
						|
#include "cset.h"
 | 
						|
#include "cpu.h"
 | 
						|
#include "vpp.h"
 | 
						|
#include "vdc.h"
 | 
						|
 | 
						|
#include "emuapi.h"
 | 
						|
 | 
						|
 | 
						|
typedef struct
 | 
						|
{
 | 
						|
  unsigned char r;
 | 
						|
  unsigned char g;
 | 
						|
  unsigned char b;
 | 
						|
} PALETTE_ENTRY;
 | 
						|
 | 
						|
 | 
						|
#define COL_SP0   0x01
 | 
						|
#define COL_SP1   0x02
 | 
						|
#define COL_SP2   0x04
 | 
						|
#define COL_SP3   0x08
 | 
						|
#define COL_VGRID 0x10
 | 
						|
#define COL_HGRID 0x20
 | 
						|
#define COL_VPP   0x40
 | 
						|
#define COL_CHAR  0x80
 | 
						|
 | 
						|
#define X_START     8
 | 
						|
#define Y_START		24
 | 
						|
 | 
						|
static const long colortable[16]={
 | 
						|
	0x000000,
 | 
						|
	0x0e3dd4,
 | 
						|
	0x00981b,
 | 
						|
	0x00bbd9,
 | 
						|
	0xc70008,
 | 
						|
	0xcc16b3,
 | 
						|
	0x9d8710,
 | 
						|
	0xe1dee1,
 | 
						|
	0x5f6e6b,
 | 
						|
	0x6aa1ff,
 | 
						|
	0x3df07a,
 | 
						|
	0x31ffff,
 | 
						|
	0xff4255,
 | 
						|
	0xff98ff,
 | 
						|
	0xd9ad5d,
 | 
						|
	0xffffff
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
/* The pointer to the graphics buffer And palette */
 | 
						|
 | 
						|
static PALETTE_ENTRY colors[256];
 | 
						|
static Byte * vscreen=0; //[BMPW*BMPH];
 | 
						|
 | 
						|
/* Collision buffer */
 | 
						|
static Byte * colbuf=0; //[BMPW*BMPH];
 | 
						|
 | 
						|
Byte coltab[256];
 | 
						|
 | 
						|
long clip_low;
 | 
						|
long clip_high;
 | 
						|
 | 
						|
 | 
						|
static void create_cmap(void);
 | 
						|
static void draw_char(Byte ypos,Byte xpos,Byte chr,Byte col);
 | 
						|
static void draw_grid(void);
 | 
						|
INLINE extern void mputvid(unsigned int ad, unsigned int len, Byte d, Byte c);
 | 
						|
 | 
						|
 | 
						|
unsigned char * getGBuf(void)
 | 
						|
{
 | 
						|
	return(vscreen);
 | 
						|
}
 | 
						|
 | 
						|
void draw_region(void){
 | 
						|
	int i;
 | 
						|
 | 
						|
  //emu_printi(last_line);
 | 
						|
 | 
						|
	if (regionoff == 0xffff)
 | 
						|
		i = master_clk/(LINECNT-1)-5;
 | 
						|
	else
 | 
						|
		i = master_clk/22+regionoff;
 | 
						|
	//i = snapline(i, VDCwrite[0xA0], 0);
 | 
						|
 | 
						|
	if (i<0) i=0;
 | 
						|
 | 
						|
#ifdef HALFHEIGHT
 | 
						|
  i = i>>1;
 | 
						|
#else
 | 
						|
#endif
 | 
						|
 
 | 
						|
 	clip_low = last_line * (long)BMPW;
 | 
						|
	clip_high = i * (long)BMPW;
 | 
						|
	if (clip_high > BMPW*BMPH) clip_high = BMPW*BMPH;
 | 
						|
	if (clip_low < 0) clip_low=0; 
 | 
						|
	if (clip_low < clip_high) draw_display();
 | 
						|
	last_line=i;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
#define fastmputvid1(ad,d,c) if ((ad > (unsigned long)clip_low) && (ad < (unsigned long)clip_high)) { vscreen[ad]=d; colbuf[ad] |= c; coltab[c] |= colbuf[ad];}
 | 
						|
#define fastmputvid2(ad,d,c) if ((ad > (unsigned long)clip_low) && (ad < (unsigned long)clip_high)) { vscreen[ad]=d; colbuf[ad] |= c; coltab[c] |= colbuf[ad];vscreen[ad+1]=d; colbuf[ad+1] |= c; coltab[c] |= colbuf[ad+1];}
 | 
						|
//#define fastmputvid1(ad,d,c) mputvid(ad,1,d,c);
 | 
						|
//#define fastmputvid2(ad,d,c) mputvid(ad,2,d,c);
 | 
						|
 
 | 
						|
 | 
						|
INLINE void mputvid(unsigned int ad, unsigned int len, Byte d, Byte c){
 | 
						|
	if ((ad > (unsigned long)clip_low) && (ad < (unsigned long)clip_high)) {
 | 
						|
		unsigned int i;
 | 
						|
// JMH
 | 
						|
        Byte d1; 
 | 
						|
		d1 = d;
 | 
						|
		if ( ((len & 3)==0) && (sizeof(unsigned long) == 4) && ((ad & 3) == 0) ) 
 | 
						|
		{
 | 
						|
			unsigned long dddd = (((unsigned long)d1) & 0xff) | ((((unsigned long)d1) & 0xff) << 8) | ((((unsigned long)d1) & 0xff) << 16) | ((((unsigned long)d1) & 0xff) << 24);
 | 
						|
			unsigned long cccc = (((unsigned long)c) & 0xff) | ((((unsigned long)c) & 0xff) << 8) | ((((unsigned long)c) & 0xff) << 16) | ((((unsigned long)c) & 0xff) << 24);
 | 
						|
			for (i=0; i<len>>2; i++) {
 | 
						|
				*((unsigned long*)(vscreen+ad)) = dddd;
 | 
						|
				cccc |= *((unsigned long*)(colbuf+ad));
 | 
						|
				*((unsigned long*)(colbuf+ad)) = cccc;
 | 
						|
				coltab[c] |= ((cccc | (cccc >> 8) | (cccc >> 16) | (cccc >> 24)) & 0xff);
 | 
						|
				ad += 4;
 | 
						|
			}
 | 
						|
		} else 
 | 
						|
		{
 | 
						|
			for (i=0; i<len; i++) {
 | 
						|
				vscreen[ad]=d1;
 | 
						|
				colbuf[ad] |= c;
 | 
						|
				coltab[c] |= colbuf[ad++];
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
static void create_cmap(void){
 | 
						|
  int i;
 | 
						|
 | 
						|
  /* Initialise parts of the colors array */
 | 
						|
  for (i = 0; i < 16; i++) {
 | 
						|
      /* Use the color values from the color table */
 | 
						|
      colors[i+32].r = colors[i].r = (colortable[i] & 0xff0000) >> 16; //18;
 | 
						|
      colors[i+32].g = colors[i].g = (colortable[i] & 0x00ff00) >> 8; //10;
 | 
						|
      colors[i+32].b = colors[i].b = (colortable[i] & 0x0000ff) >> 0; //2;
 | 
						|
  }
 | 
						|
 | 
						|
  for (i = 16; i < 32; i++) {
 | 
						|
      /* Half-bright colors for the 50% scanlines */
 | 
						|
      colors[i+32].r = colors[i].r = colors[i-16].r/2;
 | 
						|
      colors[i+32].g = colors[i].g = colors[i-16].g/2;
 | 
						|
      colors[i+32].b = colors[i].b = colors[i-16].b/2;
 | 
						|
  }
 | 
						|
	
 | 
						|
  for (i = 64; i < 256; i++) colors[i].r = colors[i].g = colors[i].b = 0;
 | 
						|
  
 | 
						|
  for (i=0;i<256;i++)
 | 
						|
  {  
 | 
						|
	emu_SetPaletteEntry(colors[i].r, colors[i].g, colors[i].b, i);
 | 
						|
  }
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
static void draw_char(Byte ypos,Byte xpos,Byte chr,Byte col){
 | 
						|
	int j,c;
 | 
						|
	Byte cl,d1;
 | 
						|
	int y,b,n;
 | 
						|
	unsigned int pnt;
 | 
						|
 | 
						|
#ifdef HALFHEIGHT
 | 
						|
  y = ypos>>1;
 | 
						|
#else
 | 
						|
  y=(ypos & 0xFE);
 | 
						|
#endif
 | 
						|
	pnt = y * BMPW + (xpos-8)+BORDERW;
 | 
						|
 | 
						|
	ypos = ypos >> 1;
 | 
						|
	n = 8 - (ypos % 8) - (chr % 8);
 | 
						|
	if (n < 3) n = n + 7;
 | 
						|
	
 | 
						|
#ifdef HALFHEIGHT
 | 
						|
  if ((pnt+BMPW*n >= (unsigned long)clip_low) && (pnt <= (unsigned long)clip_high)) {
 | 
						|
#else
 | 
						|
  if ((pnt+BMPW*2*n >= (unsigned long)clip_low) && (pnt <= (unsigned long)clip_high)) {
 | 
						|
#endif
 | 
						|
 | 
						|
		c=(int)chr + ypos;
 | 
						|
		if (col & 0x01) c+=256;
 | 
						|
		if (c > 511) c=c-512;
 | 
						|
 | 
						|
		cl = ((col & 0x0E) >> 1);
 | 
						|
		cl = ((cl&2) | ((cl&1)<<2) | ((cl&4)>>2)) + 8;
 | 
						|
 | 
						|
#ifdef HALFHEIGHT
 | 
						|
    if ((y>0) && (y<112) && (xpos<157)) {
 | 
						|
#else
 | 
						|
    if ((y>0) && (y<232) && (xpos<157)) {
 | 
						|
#endif
 | 
						|
			for (j=0; j<n; j++) {
 | 
						|
				d1 = cset[c+j];
 | 
						|
				for (b=0; b<8; b++) {
 | 
						|
					if (d1 & 0x80) {
 | 
						|
#ifdef HALFHEIGHT
 | 
						|
            if ((xpos-8+b < 160) && (y+j < 120)) {
 | 
						|
#else
 | 
						|
            if ((xpos-8+b < 160) && (y+j < 240)) {
 | 
						|
#endif
 | 
						|
							fastmputvid1(pnt,cl,COL_CHAR);
 | 
						|
#ifdef HALFHEIGHT
 | 
						|
#else
 | 
						|
              fastmputvid1(pnt+BMPW,cl,COL_CHAR);
 | 
						|
#endif
 | 
						|
						}
 | 
						|
					}
 | 
						|
					pnt+=1;
 | 
						|
					d1 = d1 << 1;
 | 
						|
				}
 | 
						|
#ifdef HALFHEIGHT
 | 
						|
        pnt += BMPW-8;
 | 
						|
#else
 | 
						|
        pnt += BMPW*2-8;
 | 
						|
#endif
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
static void draw_grid(void){
 | 
						|
	unsigned int pnt, pn1;
 | 
						|
	Byte mask,d;
 | 
						|
	int j,i,x,w;
 | 
						|
	Byte color;
 | 
						|
 | 
						|
	if (VDCwrite[0xA0] & 0x40) {
 | 
						|
		for(j=0; j<9; j++) {
 | 
						|
#ifdef HALFHEIGHT
 | 
						|
      pnt = (((j*12)+12) * BMPW);
 | 
						|
#else
 | 
						|
      pnt = (((j*24)+24) * BMPW);
 | 
						|
#endif
 | 
						|
			for (i=0; i<9; i++) {
 | 
						|
				pn1 = pnt + (i * 16) + BORDERW;
 | 
						|
				color = ColorVector[j*24+24];
 | 
						|
				fastmputvid2(pn1, (color & 0x07) | ((color & 0x40) >> 3) | (color & 0x80 ? 0 : 8), COL_HGRID);
 | 
						|
				color = ColorVector[j*24+25];
 | 
						|
				fastmputvid2(pn1+BMPW, (color & 0x07) | ((color & 0x40) >> 3) | (color & 0x80 ? 0 : 8), COL_HGRID);
 | 
						|
#ifdef HALFHEIGHT
 | 
						|
#else
 | 
						|
        color = ColorVector[j*24+26];
 | 
						|
        fastmputvid2(pn1+BMPW*2, (color & 0x07) | ((color & 0x40) >> 3) | (color & 0x80 ? 0 : 8), COL_HGRID);
 | 
						|
#endif
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	// horizontal 
 | 
						|
	mask=0x01;
 | 
						|
	for(j=0; j<9; j++) {
 | 
						|
#ifdef HALFHEIGHT
 | 
						|
    pnt = (((j*12)+12) * BMPW);
 | 
						|
#else
 | 
						|
    pnt = (((j*24)+24) * BMPW);
 | 
						|
#endif
 | 
						|
		for (i=0; i<9; i++) {
 | 
						|
			pn1 = pnt + (i * 16) + BORDERW;
 | 
						|
#ifdef HALFHEIGHT
 | 
						|
      if ((pn1+BMPW*2 >= (unsigned long)clip_low) && (pn1 <= (unsigned long)clip_high)) {
 | 
						|
#else
 | 
						|
      if ((pn1+BMPW*3 >= (unsigned long)clip_low) && (pn1 <= (unsigned long)clip_high)) {
 | 
						|
#endif
 | 
						|
				d=VDCwrite[0xC0 + i];
 | 
						|
				if (j == 8) {
 | 
						|
					d=VDCwrite[0xD0+i];
 | 
						|
					mask=1;
 | 
						|
				}
 | 
						|
				if (d & mask)	{
 | 
						|
					color = ColorVector[j*24+24];
 | 
						|
					mputvid(pn1, 18, (color & 0x07) | ((color & 0x40) >> 3) | (color & 0x80 ? 0 : 8), COL_HGRID);
 | 
						|
					color = ColorVector[j*24+25];
 | 
						|
					mputvid(pn1+BMPW, 18, (color & 0x07) | ((color & 0x40) >> 3) | (color & 0x80 ? 0 : 8), COL_HGRID);
 | 
						|
#ifdef HALFHEIGHT
 | 
						|
#else
 | 
						|
          color = ColorVector[j*24+26];
 | 
						|
          mputvid(pn1+BMPW*2, 18, (color & 0x07) | ((color & 0x40) >> 3) | (color & 0x80 ? 0 : 8), COL_HGRID);
 | 
						|
#endif
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
		mask = mask << 1;
 | 
						|
	}
 | 
						|
 | 
						|
	// vertical
 | 
						|
	mask=0x01;
 | 
						|
	w=2;
 | 
						|
	if (VDCwrite[0xA0] & 0x80) w=16;
 | 
						|
	for(j=0; j<10; j++) {
 | 
						|
		pnt=(j*16);
 | 
						|
		mask=0x01;
 | 
						|
		d=VDCwrite[0xE0+j];
 | 
						|
		for (x=0; x<8; x++) {
 | 
						|
#ifdef HALFHEIGHT
 | 
						|
      pn1 = pnt + (((x*12)+12) * BMPW) + BORDERW;
 | 
						|
#else
 | 
						|
      pn1 = pnt + (((x*24)+24) * BMPW) + BORDERW;
 | 
						|
#endif
 | 
						|
			if (d & mask) {
 | 
						|
#ifdef HALFHEIGHT
 | 
						|
        for(i=0; i<12; i++) {
 | 
						|
#else
 | 
						|
        for(i=0; i<24; i++) {
 | 
						|
#endif
 | 
						|
					if ((pn1 >= (unsigned long)clip_low) && (pn1 <= (unsigned long)clip_high)) {
 | 
						|
						color = ColorVector[x*24+24+i];
 | 
						|
						mputvid(pn1, w, (color & 0x07) | ((color & 0x40) >> 3) | (color & 0x80 ? 0 : 8), COL_VGRID);
 | 
						|
					}
 | 
						|
					pn1+=BMPW;
 | 
						|
				}
 | 
						|
			}
 | 
						|
			mask = mask << 1;
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void finish_display(void){
 | 
						|
	vpp_finish_bmp(vscreen, 9, 5, BMPW-9, BMPH-5, BMPW, BMPH);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void clear_collision(void){
 | 
						|
	load_colplus(colbuf);
 | 
						|
	coltab[0x01]=coltab[0x02]=0;
 | 
						|
	coltab[0x04]=coltab[0x08]=0;
 | 
						|
	coltab[0x10]=coltab[0x20]=0;
 | 
						|
	coltab[0x40]=coltab[0x80]=0;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void draw_display(void){
 | 
						|
	int i,j,x,sm,t;
 | 
						|
	Byte y,xt,yt,b,d1,cl,c;
 | 
						|
	unsigned int pnt,pnt2;
 | 
						|
 | 
						|
#ifdef HALFHEIGHT
 | 
						|
  for (i=clip_low/BMPW; i<clip_high/BMPW; i++) {
 | 
						|
    memset(vscreen+i*BMPW, ((ColorVector[i<<1] & 0x38) >> 3) | (ColorVector[i<<1] & 0x80 ? 0 : 8), BMPW);
 | 
						|
  }
 | 
						|
#else
 | 
						|
  for (i=clip_low/BMPW; i<clip_high/BMPW; i++) {
 | 
						|
    memset(vscreen+i*BMPW, ((ColorVector[i] & 0x38) >> 3) | (ColorVector[i] & 0x80 ? 0 : 8), BMPW);
 | 
						|
  }
 | 
						|
#endif
 | 
						|
	
 | 
						|
	if (VDCwrite[0xA0] & 0x08) draw_grid();
 | 
						|
 | 
						|
	if (useforen && (!(VDCwrite[0xA0] & 0x20))) return;
 | 
						|
	
 | 
						|
	for(i=0x10; i<0x40; i+=4) draw_char(VDCwrite[i],VDCwrite[i+1],VDCwrite[i+2],VDCwrite[i+3]);
 | 
						|
 | 
						|
	pnt=0x40;
 | 
						|
	for(i=0; i<4; i++) {
 | 
						|
		x=y=248;
 | 
						|
		for (j=0; j<4; j++){
 | 
						|
			xt = VDCwrite[pnt+j*4+1];
 | 
						|
			yt = VDCwrite[pnt+j*4];
 | 
						|
      if ((xt<240) && (yt<240)){
 | 
						|
				x=xt;
 | 
						|
				y=yt;
 | 
						|
				break;
 | 
						|
			}
 | 
						|
		}
 | 
						|
		for(j=0; j<4; j++) {
 | 
						|
			draw_char(y,x,VDCwrite[pnt+2],VDCwrite[pnt+3]);
 | 
						|
			x+=16;
 | 
						|
			pnt+=4;
 | 
						|
		}
 | 
						|
	}
 | 
						|
	
 | 
						|
	c=8;
 | 
						|
	for (i=12; i>=0; i -=4) {
 | 
						|
		pnt2 = 0x80 + (i * 2);
 | 
						|
#ifdef HALFHEIGHT
 | 
						|
    y = VDCwrite[i]>>1;
 | 
						|
#else
 | 
						|
    y = VDCwrite[i];
 | 
						|
#endif
 | 
						|
		x = VDCwrite[i+1]-8;
 | 
						|
		t = VDCwrite[i+2];
 | 
						|
		cl = ((t & 0x38) >> 3);
 | 
						|
		cl = ((cl&2) | ((cl&1)<<2) | ((cl&4)>>2)) + 8;
 | 
						|
//#ifdef HALFHEIGHT
 | 
						|
//    if ((x<164) && (y>0) && (y<112)) {
 | 
						|
//#else
 | 
						|
    if ((x<164) && (y>0) && (y<232)) {
 | 
						|
//#endif
 | 
						|
			pnt = y * BMPW + x + BORDERW + sproff;
 | 
						|
			if ((pnt+BMPW*16 >= (unsigned long)clip_low) && (pnt <= (unsigned long)clip_high)) {
 | 
						|
				for (j=0; j<8; j++) {
 | 
						|
					sm = (((j%2==0) && (((t>>1) & 1) != (t & 1))) || ((j%2==1) && (t & 1))) ? 1 : 0;
 | 
						|
					d1 = VDCwrite[pnt2++];
 | 
						|
					for (b=0; b<8; b++) {
 | 
						|
						if (d1 & 0x01) {
 | 
						|
#ifdef HALFHEIGHT
 | 
						|
              if ((x+b+sm<160) && (y+j<129)) {
 | 
						|
#else
 | 
						|
              if ((x+b+sm<160) && (y+j<249)) {
 | 
						|
#endif
 | 
						|
								fastmputvid1(sm+pnt,cl,c);
 | 
						|
#ifdef HALFHEIGHT
 | 
						|
#else
 | 
						|
                fastmputvid1(sm+pnt+BMPW,cl,c);
 | 
						|
#endif
 | 
						|
							}
 | 
						|
						}
 | 
						|
						pnt += 1;
 | 
						|
						d1 = d1 >> 1;
 | 
						|
					}
 | 
						|
#ifdef HALFHEIGHT
 | 
						|
          pnt += BMPW-8;
 | 
						|
#else
 | 
						|
          pnt += BMPW*2-8;
 | 
						|
#endif
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
		c = c >> 1;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
void close_display(void) 
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
void init_display(void) 
 | 
						|
{
 | 
						|
	if (vscreen==0) vscreen = (Byte *)emu_Malloc(BMPW*BMPH);
 | 
						|
	if (colbuf == 0) colbuf = (Byte *)emu_Malloc(BMPW*BMPH);
 | 
						|
 | 
						|
	create_cmap();
 | 
						|
	memset(colbuf,0,BMPW*BMPH);
 | 
						|
}
 | 
						|
 |