File:  [UNIX Amiga Emulator] / uae / svga.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 16:38:19 2018 UTC (8 years, 2 months ago) by root
Branches: MAIN, BSchmidt
CVS tags: uae060, HEAD
uae-0.6.0

 /* 
  * UAE - The Un*x Amiga Emulator
  * 
  * SVGAlib interface.
  * 
  * (c) 1995 Bernd Schmidt
  */

#include "sysconfig.h"
#include "sysdeps.h"

#include <assert.h>
#include <signal.h>
#include <vga.h>
#include <vgamouse.h>
#include <vgakeyboard.h>

#include "config.h"
#include "options.h"
#include "memory.h"
#include "custom.h"
#include "newcpu.h"
#include "keyboard.h"
#include "xwin.h"
#include "keybuf.h"

#define SCODE_CURSORBLOCKUP	103	/* Cursor key block. */
#define SCODE_CURSORBLOCKLEFT 105
#define SCODE_CURSORBLOCKRIGHT 106
#define SCODE_CURSORBLOCKDOWN 108

#define SCODE_INSERT 110
#define SCODE_HOME 102
#define SCODE_PGUP 104
#define SCODE_DELETE 111
#define SCODE_END 107
#define SCODE_PGDN 109

#define SCODE_KEYPAD0	82
#define SCODE_KEYPAD1	79
#define SCODE_KEYPAD2	80
#define SCODE_KEYPAD3	81
#define SCODE_KEYPAD4	75
#define SCODE_KEYPAD5	76
#define SCODE_KEYPAD6	77
#define SCODE_KEYPAD7	71
#define SCODE_KEYPAD8	72
#define SCODE_KEYPAD9	73
#define SCODE_KEYPADENTER	96
#define SCODE_KEYPADPLUS	78
#define SCODE_KEYPADMINUS	74

#define SCODE_Q		16
#define SCODE_W		17
#define SCODE_E		18
#define SCODE_R		19
#define SCODE_T		20
#define SCODE_Y		21
#define SCODE_U		22
#define SCODE_I		23
#define SCODE_O		24
#define SCODE_P		25

#define SCODE_A		30
#define SCODE_S		31
#define SCODE_D		32
#define SCODE_F		33
#define SCODE_G		34
#define SCODE_H		35
#define SCODE_J		36
#define SCODE_K		37
#define SCODE_L		38

#define SCODE_Z		44
#define SCODE_X		45
#define SCODE_C		46
#define SCODE_V		47
#define SCODE_B		48
#define SCODE_N		49
#define SCODE_M		50

#define SCODE_ESCAPE		1
#define SCODE_ENTER		28
#define SCODE_RIGHTCONTROL	97
#define SCODE_CONTROL	97
#define SCODE_RIGHTALT	100
#define SCODE_LEFTCONTROL	29
#define SCODE_LEFTALT	56
#define SCODE_SPACE		57

#define SCODE_F1		59
#define SCODE_F2		60
#define SCODE_F3		61
#define SCODE_F4		62
#define SCODE_F5		63
#define SCODE_F6		64
#define SCODE_F7		65
#define SCODE_F8		66
#define SCODE_F9		67
#define SCODE_F10		68

#define SCODE_0 11
#define SCODE_1 2
#define SCODE_2 3
#define SCODE_3 4
#define SCODE_4 5 
#define SCODE_5 6
#define SCODE_6 7 
#define SCODE_7 8
#define SCODE_8 9
#define SCODE_9 10

#define SCODE_LEFTSHIFT 42
#define SCODE_RIGHTSHIFT 54
#define SCODE_TAB 15

#define SCODE_F11 87
#define SCODE_F12 88
#define SCODE_NEXT 81
#define SCODE_PRIOR 73
#define SCODE_BS 14
/*
#define SCODE_asciicircum 1
*/
#define SCODE_bracketleft 26
#define SCODE_bracketright 27
#define SCODE_comma 51
#define SCODE_period 52
#define SCODE_slash 53
#define SCODE_semicolon 39
#define SCODE_grave 40
#define SCODE_minus 12
#define SCODE_equal 13
#define SCODE_numbersign 41
#define SCODE_ltgt 43
#define SCODE_scrolllock 70

#define SCODE_LWIN95 125
#define SCODE_RWIN95 126
#define SCODE_MWIN95 127

static int vsize;
static vga_modeinfo modeinfo;
static char *linear_mem = NULL;
xcolnr xcolors[4096];

struct vidbuf_description gfxvidinfo;

void flush_line(int y)
{
    int target_y = y;
    
    if (screen_res < 2)
	target_y -= 8;
    if (linear_mem == NULL) {
	char *addr = gfxvidinfo.bufmem + y*gfxvidinfo.rowbytes;
	if (use_lores) {
	    addr += gfxvidinfo.pixbytes * (prev_max_diwstop - 328);
	}
	if (target_y < modeinfo.height && target_y >= 0)
	    vga_drawscanline(target_y, addr);
    }
}

void flush_block(int a, int b)
{
    abort();
}

void flush_screen(int a, int b)
{
}

static int colors_allocated;

static int get_color(int r, int g, int b, xcolnr *cnp)
{
    if (colors_allocated == 256)
	return -1;
    *cnp = colors_allocated;
    vga_setpalette(colors_allocated, doMask(r, 6, 0), doMask(g, 6, 0), doMask(b, 6, 0));
    colors_allocated++;
    return 1;
}

static void init_colors(void)
{
    int rw = 5, gw = 5, bw = 5;
    colors_allocated = 0;
    if (color_mode == 2) gw = 6;
    
    if (gfxvidinfo.pixbytes == 2)
	alloc_colors64k(rw, gw, bw, gw+bw, bw, 0);
    else
	alloc_colors256(get_color);
}

int buttonstate[3] = { 0, 0, 0 };
int lastmx, lastmy;
int newmousecounters = 0;

static int keystate[256];

static int scancode2amiga(int scancode)
{
    switch(scancode) {
     case SCODE_A: return AK_A;
     case SCODE_B: return AK_B;
     case SCODE_C: return AK_C;
     case SCODE_D: return AK_D;
     case SCODE_E: return AK_E;
     case SCODE_F: return AK_F;
     case SCODE_G: return AK_G;
     case SCODE_H: return AK_H;
     case SCODE_I: return AK_I;
     case SCODE_J: return AK_J;
     case SCODE_K: return AK_K;
     case SCODE_L: return AK_L;
     case SCODE_M: return AK_M;
     case SCODE_N: return AK_N;
     case SCODE_O: return AK_O;
     case SCODE_P: return AK_P;
     case SCODE_Q: return AK_Q;
     case SCODE_R: return AK_R;
     case SCODE_S: return AK_S;
     case SCODE_T: return AK_T;
     case SCODE_U: return AK_U;
     case SCODE_V: return AK_V;
     case SCODE_W: return AK_W;
     case SCODE_X: return AK_X;
     case SCODE_Y: return AK_Y;
     case SCODE_Z: return AK_Z;
	
     case SCODE_0: return AK_0;
     case SCODE_1: return AK_1;
     case SCODE_2: return AK_2;
     case SCODE_3: return AK_3;
     case SCODE_4: return AK_4;
     case SCODE_5: return AK_5;
     case SCODE_6: return AK_6;
     case SCODE_7: return AK_7;
     case SCODE_8: return AK_8;
     case SCODE_9: return AK_9;
	
     case SCODE_KEYPAD0: return AK_NP0;
     case SCODE_KEYPAD1: return AK_NP1;
     case SCODE_KEYPAD2: return AK_NP2;
     case SCODE_KEYPAD3: return AK_NP3;
     case SCODE_KEYPAD4: return AK_NP4;
     case SCODE_KEYPAD5: return AK_NP5;
     case SCODE_KEYPAD6: return AK_NP6;
     case SCODE_KEYPAD7: return AK_NP7;
     case SCODE_KEYPAD8: return AK_NP8;
     case SCODE_KEYPAD9: return AK_NP9;
	
     case SCODE_F1: return AK_F1;
     case SCODE_F2: return AK_F2;
     case SCODE_F3: return AK_F3;
     case SCODE_F4: return AK_F4;
     case SCODE_F5: return AK_F5;
     case SCODE_F6: return AK_F6;
     case SCODE_F7: return AK_F7;
     case SCODE_F8: return AK_F8;
     case SCODE_F9: return AK_F9;
     case SCODE_F10: return AK_F10;
	
     case SCODE_BS: return AK_BS;
     case SCODE_LEFTCONTROL: return AK_CTRL;
     case SCODE_RIGHTCONTROL: return AK_CTRL;
     case SCODE_TAB: return AK_TAB;
     case SCODE_LEFTALT: return AK_LALT;
     case SCODE_RIGHTALT: return AK_RALT;
     case SCODE_ENTER: return AK_RET;
     case SCODE_SPACE: return AK_SPC;
     case SCODE_LEFTSHIFT: return AK_LSH;
     case SCODE_RIGHTSHIFT: return AK_RSH;
     case SCODE_ESCAPE: return AK_ESC;
	
     case SCODE_INSERT:
     case SCODE_END:	
     case SCODE_HOME: break;

     case SCODE_DELETE: return AK_DEL;
     case SCODE_CURSORBLOCKUP: return AK_UP;
     case SCODE_CURSORBLOCKDOWN: return AK_DN;
     case SCODE_CURSORBLOCKLEFT: return AK_LF;
     case SCODE_CURSORBLOCKRIGHT: return AK_RT;
	
     case SCODE_F11: return AK_BACKSLASH;
/*
     case SCODE_asciicircum: return AK_00;
 */
     case SCODE_bracketleft: return AK_LBRACKET;
     case SCODE_bracketright: return AK_RBRACKET;
     case SCODE_comma: return AK_COMMA;
     case SCODE_period: return AK_PERIOD;
     case SCODE_slash: return AK_SLASH;
     case SCODE_semicolon: return AK_SEMICOLON;
     case SCODE_grave: return AK_QUOTE;
     case SCODE_minus: return AK_MINUS;
     case SCODE_equal: return AK_EQUAL;
	
	/* This one turns off screen updates. */
     case SCODE_scrolllock: return AK_inhibit;

     case SCODE_PGUP: case SCODE_RWIN95: return AK_RAMI;
     case SCODE_PGDN: case SCODE_LWIN95: return AK_LAMI; 
	
/*#ifdef KBD_LANG_DE*/
     case SCODE_numbersign: return AK_NUMBERSIGN;
     case SCODE_ltgt: return AK_LTGT;
/*#endif*/
    }
    return -1;
}

static void my_kbd_handler(int scancode, int newstate)
{
    int akey = scancode2amiga(scancode);
    
    assert(scancode >= 0 && scancode < 0x100);
    if (scancode == SCODE_F12)
    	specialflags |= SPCFLAG_BRK;
    if (keystate[scancode] == newstate)
    	return;
    keystate[scancode] = newstate;

    if (akey == -1)
    	return;

    if (newstate == KEY_EVENTPRESS) {
	if (akey == AK_inhibit)
	    inhibit_frame ^= 1;
	else
	    record_key (akey << 1);
    } else
    	record_key ((akey << 1) | 1);
    
    /* "Affengriff" */
    if(keystate[AK_CTRL] && keystate[AK_LAMI] && keystate[AK_RAMI])
    	MC68000_reset();
}

int graphics_init(void)
{
    int i;
    int vgamode;
    if ((screen_res == 1 || screen_res == 2) && color_mode != 0) {
	fprintf(stderr, "Sorry, this combination of color and video mode is not supported.\n");
	return 0;
    }
    switch (screen_res) {
     case 0: vgamode = (color_mode == 0 ? G320x200x256 
			: color_mode == 1 ? G320x200x32K 
			: G320x200x64K);
	    break;
     case 1: vgamode = G320x240x256; break;
     case 2: vgamode = G320x400x256; break;
     case 3: 
     case 4: vgamode = (color_mode == 0 ? G800x600x256 
			: color_mode == 1 ? G800x600x32K 
			: G800x600x64K);
	break;
     default:
	printf("Invalid screen mode.\n");
	return 0;
    }
    vga_init();
    modeinfo = *vga_getmodeinfo (vgamode);
    if (modeinfo.bytesperpixel == 0) {
	printf("Got a bogus value from SVGAlib... %s.\n",
	       screen_res == 1 || screen_res == 2 ? "trying to fix it" : "giving up");
	if (screen_res != 1 && screen_res != 2)
	    return 0;
	modeinfo.bytesperpixel = 1;
	modeinfo.linewidth = 320;
    }
    gfxvidinfo.pixbytes = modeinfo.bytesperpixel;
    if (vga_setmode(vgamode) < 0) {
	sleep(1);
	vga_setmode(TEXT);
	fprintf(stderr, "SVGAlib doesn't like my video mode. Giving up.\n");
	return 0;
    }
	
    if ((modeinfo.flags & CAPABLE_LINEAR) && !use_lores && !use_xhair) {
	if (vga_setlinearaddressing() != -1) {
	    linear_mem = (char *)vga_getgraphmem();
	    printf("Using linear addressing: %p.\n", linear_mem);
	}
    }
    
    vsize = dont_want_aspect ? numscrlines : 2*numscrlines;
    gfxvidinfo.maxblocklines = 0;
/*    printf("%d %d %d\n", modeinfo.linewidth, modeinfo.bytesperpixel, modeinfo.maxpixels);*/
    if (linear_mem) {
	gfxvidinfo.bufmem = linear_mem;
	gfxvidinfo.rowbytes = modeinfo.linewidth;
    } else {
	gfxvidinfo.rowbytes = 800 * gfxvidinfo.pixbytes;
	gfxvidinfo.bufmem = malloc(gfxvidinfo.rowbytes * vsize);
	memset(gfxvidinfo.bufmem, 0, gfxvidinfo.rowbytes * vsize);
    }
    init_colors();
    vga_setmousesupport(1);
    mouse_init("/dev/mouse",vga_getmousetype(),10);
    if (keyboard_init() != 0)
    	abort();
    keyboard_seteventhandler(my_kbd_handler);
    keyboard_translatekeys(DONT_CATCH_CTRLC);
    
    buttonstate[0] = buttonstate[1] = buttonstate[2] = 0;
    for(i = 0; i < 256; i++) 
	keystate[i] = 0;

    lastmx = lastmy = 0;
    newmousecounters = 0;

    mouse_setxrange(-1000,1000);
    mouse_setyrange(-1000,1000);
    mouse_setposition(0,0);
    
    return 1;
}

void graphics_leave(void)
{
    sleep(1); /* Maybe this will fix the "screen full of garbage" problem */
    vga_setmode(TEXT);
    keyboard_close();
}

void handle_events(void)
{
    int button = mouse_getbutton();
    
    keyboard_update();
    mouse_update();
    lastmx += mouse_getx();
    lastmy += mouse_gety();
    mouse_setposition(0,0);

    buttonstate[0] = button & 4;
    buttonstate[1] = button & 2;
    buttonstate[2] = button & 1;
}

int debuggable(void)
{
    return 0;
}

int needmousehack(void)
{
    return 0;
}

void LED(int on)
{
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.