Source to src/i_video.c


Enter a symbol's name here to quickly find it.

// Emacs style mode select   -*- C++ -*- 
//-----------------------------------------------------------------------------
//
// $Id:$
//
// Copyright (C) 1993-1996 by id Software, Inc.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// $Log:$
//
// DESCRIPTION:
//	DOOM graphics stuff for X11, UNIX.
//
//-----------------------------------------------------------------------------

static const char
rcsid[] = "$Id: i_x.c,v 1.6 1997/02/03 22:45:10 b1 Exp $";

#include <stdlib.h>
#include <unistd.h>
#include <stdarg.h>
#include <sys/time.h>
#include <sys/types.h>

#include <netinet/in.h>
#include <signal.h>


#include <go32.h>
#include <pc.h>
#include <dpmi.h>
#include <dos.h>
#include <sys/nearptr.h>

#include "doomstat.h"
#include "i_system.h"
#include "v_video.h"
#include "m_argv.h"
#include "d_main.h"

#include "doomdef.h"

//dosstuff -newly added
byte* dascreen;
_go32_dpmi_seginfo oldkeyinfo,newkeyinfo;
volatile char keydown[128];
volatile char extendedkeydown[128];
volatile char nextkeyextended;
void initkeyhandler();
void killkeyhandler();
void keyhandler();
char oldkeystate[128];
char oldextendedkeystate[128];

void initkeyhandler()
{
int i;

for (i=0;i<128;i++) keydown[i]=0;
for (i=0;i<128;i++) extendedkeydown[i]=0;
for (i=0;i<128;i++) oldkeystate[i]=0;
for (i=0;i<128;i++) oldextendedkeystate[i]=0;
nextkeyextended=0;

asm("cli");
_go32_dpmi_get_protected_mode_interrupt_vector(9, &oldkeyinfo);
newkeyinfo.pm_offset=(int)keyhandler;
newkeyinfo.pm_selector=_go32_my_cs();
_go32_dpmi_allocate_iret_wrapper(&newkeyinfo);
_go32_dpmi_set_protected_mode_interrupt_vector(9, &newkeyinfo);
asm("sti");
}

void killkeyhandler()
{
asm("cli");
_go32_dpmi_set_protected_mode_interrupt_vector(9, &oldkeyinfo);
_go32_dpmi_free_iret_wrapper(&newkeyinfo);
asm("sti");
}

void keyhandler()
{
unsigned char keyhandlercurrkey;

asm("cli");
keyhandlercurrkey=inportb(0x60);

if (nextkeyextended)
  {
  if ((keyhandlercurrkey&0x80)==0)
    extendedkeydown[keyhandlercurrkey&0x7f]=1;
  else
    extendedkeydown[keyhandlercurrkey&0x7f]=0;
  nextkeyextended=0;
  }
else
  {
  if ((keyhandlercurrkey&0x80)==0)
    keydown[keyhandlercurrkey&0x7f]=1;
  else
    keydown[keyhandlercurrkey&0x7f]=0;
  }

if (keyhandlercurrkey==0xe0)
  nextkeyextended=1;

if ((keydown[0x1d])&&(keyhandlercurrkey==0x2e))
  {
  asm ("movb $0x79, %%al
        call ___djgpp_hw_exception"
       : : :"%eax","%ebx","%ecx","%edx","%esi","%edi","memory");
  }

//reset keyoard
{char b; b=inportb(0x61); outportb(0x61,b|80); outportb(0x61,b); outportb(0x20,0x20);}
asm("sti");
}

byte ASCIINames[] =		// Unshifted ASCII for scan codes
					{
//	 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
	0  ,27 ,'1','2','3','4','5','6','7','8','9','0','-','=',8  ,9  ,	// 0
	'q','w','e','r','t','y','u','i','o','p','[',']',13 ,0  ,'a','s',	// 1
	'd','f','g','h','j','k','l',';',39 ,'`',0  ,92 ,'z','x','c','v',	// 2
	'b','n','m',',','.','/',0  ,'*',0  ,' ',0  ,0  ,0  ,0  ,0  ,0  ,	// 3
	0  ,0  ,0  ,0  ,0  ,0  ,0  ,'7','8','9','-','4','5','6','+','1',	// 4
	'2','3','0',127,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,	// 5
	0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,	// 6
	0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0		// 7
					};

//end of newly added stuff


void I_ShutdownGraphics(void)
{
  __dpmi_regs r;


  killkeyhandler();
  r.x.ax=0x3;
  __dpmi_int(0x10,&r);

}



//
// I_StartFrame
//
void I_StartFrame (void)
{
    // er?

}


void I_GetEvent()
  {
  __dpmi_regs r;
  event_t event;
  char tempkey[128];
  char tempextendedkey[128];
  int i;
  int xmickeys,ymickeys,buttons;
  static int lastbuttons=0;

  //key presses
  asm("cli");
  for (i=0;i<128;i++)
    {
    tempkey[i]=keydown[i];
    tempextendedkey[i]=extendedkeydown[i];
    }
  asm("sti");
  for (i=0;i<128;i++)
    {
    if ((tempkey[i]==1)&&(oldkeystate[i]==0))
      {
      event.type=ev_keydown;
      if (ASCIINames[i]!=0)
        event.data1=ASCIINames[i];
      else
        event.data1=i+0x80;
      D_PostEvent(&event);
      }
    if ((tempkey[i]==0)&&(oldkeystate[i]==1))
      {
      event.type=ev_keyup;
      if (ASCIINames[i]!=0)
        event.data1=ASCIINames[i];
      else
        event.data1=i+0x80;
      D_PostEvent(&event);
      }
    if ((tempextendedkey[i]==1)&&(oldextendedkeystate[i]==0))
      {
      event.type=ev_keydown;
      switch (i)
        {
        case 0x48: event.data1=KEY_UPARROW; D_PostEvent(&event); break;
        case 0x4d: event.data1=KEY_RIGHTARROW; D_PostEvent(&event); break;
        case 0x50: event.data1=KEY_DOWNARROW; D_PostEvent(&event); break;
        case 0x4b: event.data1=KEY_LEFTARROW; D_PostEvent(&event); break;
        }
      }
    if ((tempextendedkey[i]==0)&&(oldextendedkeystate[i]==1))
      {
      event.type=ev_keyup;
      switch (i)
        {
        case 0x48: event.data1=KEY_UPARROW; D_PostEvent(&event); break;
        case 0x4d: event.data1=KEY_RIGHTARROW; D_PostEvent(&event); break;
        case 0x50: event.data1=KEY_DOWNARROW; D_PostEvent(&event); break;
        case 0x4b: event.data1=KEY_LEFTARROW; D_PostEvent(&event); break;
        }
      }
    }
  memcpy(oldkeystate,tempkey,128);
  memcpy(oldextendedkeystate,tempextendedkey,128);

  //mouse movement

  r.x.ax=0x0b;
  __dpmi_int(0x33,&r);
  xmickeys=(signed short)r.x.cx;
  ymickeys=(signed short)r.x.dx;
  r.x.ax=0x03;
  __dpmi_int(0x33,&r);
  buttons=r.x.bx;

  event.type=ev_mouse;
  event.data1=buttons; //???
  event.data2=xmickeys;
  event.data3=-ymickeys;
  if ((xmickeys!=0)||(ymickeys!=0)||(buttons!=lastbuttons))
    D_PostEvent(&event);
  lastbuttons=buttons;

  }


//
// I_StartTic
//
void I_StartTic()
  {
  I_GetEvent();
  //i dont think i have to do anything else here

  }



//
// I_UpdateNoBlit
//
void I_UpdateNoBlit (void)
{
    // what is this?
}

void I_FinishUpdate(void)
  {
    static int	lasttic;
    int		tics;
    int		i;
    // UNUSED static unsigned char *bigscreen=0;

    // draws little dots on the bottom of the screen
    if (devparm)
    {

	i = I_GetTime();
	tics = i - lasttic;
	lasttic = i;
	if (tics > 20) tics = 20;

	for (i=0 ; i<tics*2 ; i+=2)
	    screens[0][ (SCREENHEIGHT-1)*SCREENWIDTH + i] = 0xff;
	for ( ; i<20*2 ; i+=2)
	    screens[0][ (SCREENHEIGHT-1)*SCREENWIDTH + i] = 0x0;
    
    }

  //blast it to the screen
  memcpy(dascreen,screens[0],SCREENWIDTH*SCREENHEIGHT);
  }

//
// I_ReadScreen
//
void I_ReadScreen (byte* scr)
{
    memcpy (scr, screens[0], SCREENWIDTH*SCREENHEIGHT);
}


void I_SetPalette (byte* palette)
  {
  int c,i;

  outportb(0x3c8,0);
  for (i=0;i<256;i++)
    {
    c=gammatable[usegamma][*palette++];
    outportb(0x3c9,c>>2);
    c=gammatable[usegamma][*palette++];
    outportb(0x3c9,c>>2);
    c=gammatable[usegamma][*palette++];
    outportb(0x3c9,c>>2);
    }
  }


void I_InitGraphics(void)
  {
  static int firsttime=1;
  __dpmi_regs r;

  __djgpp_nearptr_enable();

  if (!firsttime)
    return;
  firsttime=0;

  //enter graphics mode
  r.x.ax=0x13;
  __dpmi_int(0x10,&r);
  dascreen=(byte *)(__djgpp_conventional_base+0xa0000);
  screens[0]=(byte *)malloc(SCREENWIDTH*SCREENHEIGHT);

  //init the mouse
  r.x.ax=0;
  __dpmi_int(0x33,&r);
  r.x.ax=2;
  __dpmi_int(0x33,&r); //hide cursor
  r.x.ax=0x0b;
  __dpmi_int(0x33,&r); //reset micket count

  //init keyboard
  initkeyhandler();
  }



int	inited;