📄 i_ibm.c
字号:
// extern char __begtext;
// extern char ___argc;
// int n,d;
//
// allocate a decent stack for real mode ISRs
//
realstackseg = (int)I_AllocLow (1024) >> 4;
//
// lock the entire program down
//
// _dpmi_lockregion (&__begtext, &___argc - &__begtext);
//
// catch divide by 0 exception
//
#if 0
segread(&segregs);
regs.w.ax = 0x0203; // DPMI set processor exception handler vector
regs.w.bx = 0; // int 0
regs.w.cx = segregs.cs;
regs.x.edx = (int)&I_DivException;
printf ("%x : %x\n",regs.w.cx, regs.x.edx);
int386( DPMI_INT, ®s, ®s);
#endif
#if 0
n = I_SetDivException ();
printf ("return: %i\n",n);
n = 100;
d = 0;
printf ("100 / 0 = %i\n",n/d);
exit (1);
#endif
}
/*
============================================================================
TIMER INTERRUPT
============================================================================
*/
void (__interrupt __far *oldtimerisr) ();
/*
void IO_ColorBlack (int r, int g, int b)
{
_outbyte (PEL_WRITE_ADR,0);
_outbyte(PEL_DATA,r);
_outbyte(PEL_DATA,g);
_outbyte(PEL_DATA,b);
}
*/
/*
================
=
= IO_TimerISR
=
================
*/
//void __interrupt IO_TimerISR (void)
void __interrupt __far IO_TimerISR (void)
{
ticcount++;
_outbyte(0x20,0x20); // Ack the interrupt
}
/*
=====================
=
= IO_SetTimer0
=
= Sets system timer 0 to the specified speed
=
=====================
*/
void IO_SetTimer0(int speed)
{
if (speed > 0 && speed < 150)
I_Error ("INT_SetTimer0: %i is a bad value",speed);
_outbyte(0x43,0x36); // Change timer 0
_outbyte(0x40,speed);
_outbyte(0x40,speed >> 8);
}
/*
===============
=
= IO_StartupTimer
=
===============
*/
/*
void IO_StartupTimer (void)
{
oldtimerisr = _dos_getvect(TIMERINT);
_dos_setvect (0x8000 | TIMERINT, IO_TimerISR);
IO_SetTimer0 (VBLCOUNTER);
}
*/
void IO_ShutdownTimer (void)
{
if (oldtimerisr)
{
IO_SetTimer0 (0); // back to 18.4 ips
_dos_setvect (TIMERINT, oldtimerisr);
}
}
//===========================================================================
/*
===============
=
= I_Init
=
= hook interrupts and set graphics mode
=
===============
*/
void I_Init (void)
{
extern void I_StartupTimer(void);
novideo = M_CheckParm("novideo");
ST_Message(" I_StartupDPMI\n");
I_StartupDPMI();
ST_Message(" I_StartupMouse ");
I_StartupMouse();
// tprintf("I_StartupJoystick ",1);
// I_StartupJoystick();
// tprintf("I_StartupKeyboard ",1);
// I_StartupKeyboard();
ST_Message(" S_Init... ");
S_Init();
//IO_StartupTimer();
S_Start();
}
/*
===============
=
= I_Shutdown
=
= return to default system state
=
===============
*/
void I_Shutdown (void)
{
I_ShutdownGraphics ();
IO_ShutdownTimer ();
S_ShutDown ();
I_ShutdownMouse ();
I_ShutdownKeyboard ();
IO_SetTimer0 (0);
}
/*
================
=
= I_Error
=
================
*/
void I_Error (char *error, ...)
{
union REGS regs;
va_list argptr;
D_QuitNetGame ();
I_Shutdown ();
va_start (argptr,error);
regs.x.eax = 0x3;
int386(0x10, ®s, ®s);
vprintf (error,argptr);
va_end (argptr);
printf ("\n");
exit (1);
}
//--------------------------------------------------------------------------
//
// I_Quit
//
// Shuts down net game, saves defaults, prints the exit text message,
// goes to text mode, and exits.
//
//--------------------------------------------------------------------------
void I_Quit(void)
{
D_QuitNetGame();
M_SaveDefaults();
I_Shutdown();
// scr = (byte *)W_CacheLumpName("ENDTEXT", PU_CACHE);
/*
memcpy((void *)0xb8000, scr, 80*25*2);
regs.w.ax = 0x0200;
regs.h.bh = 0;
regs.h.dl = 0;
regs.h.dh = 23;
int386(0x10, (const union REGS *)®s, ®s); // Set text pos
_settextposition(24, 1);
*/
printf("\nHexen: Beyond Heretic\n");
exit(0);
}
/*
===============
=
= I_ZoneBase
=
===============
*/
byte *I_ZoneBase (int *size)
{
int meminfo[32];
int heap;
byte *ptr;
memset (meminfo,0,sizeof(meminfo));
segread(&segregs);
segregs.es = segregs.ds;
regs.w.ax = 0x500; // get memory info
regs.x.edi = (int)&meminfo;
int386x( 0x31, ®s, ®s, &segregs );
heap = meminfo[0];
ST_Message (" DPMI memory: 0x%x, ",heap);
ST_Message ("Maxzone: 0x%x\n", maxzone);
do
{
heap -= 0x10000; // leave 64k alone
if (heap > maxzone)
heap = maxzone;
ptr = malloc (heap);
} while (!ptr);
ST_Message (" 0x%x allocated for zone, ", heap);
ST_Message ("ZoneBase: 0x%X\n", (int)ptr);
if (heap < 0x180000)
I_Error (" Insufficient DPMI memory!");
#if 0
regs.w.ax = 0x501; // allocate linear block
regs.w.bx = heap>>16;
regs.w.cx = heap&0xffff;
int386( 0x31, ®s, ®s);
if (regs.w.cflag)
I_Error (" Couldn't allocate DPMI memory!");
block = (regs.w.si << 16) + regs.w.di;
#endif
*size = heap;
return ptr;
}
/*
=============
=
= I_AllocLow
=
=============
*/
byte *I_AllocLow (int length)
{
byte *mem;
// DPMI call 100h allocates DOS memory
segread(&segregs);
regs.w.ax = 0x0100; // DPMI allocate DOS memory
regs.w.bx = (length+15) / 16;
int386( DPMI_INT, ®s, ®s);
// segment = regs.w.ax;
// selector = regs.w.dx;
if (regs.w.cflag != 0)
I_Error ("I_AllocLow: DOS alloc of %i failed, %i free",
length, regs.w.bx*16);
mem = (void *) ((regs.x.eax & 0xFFFF) << 4);
memset (mem,0,length);
return mem;
}
/*
============================================================================
NETWORKING
============================================================================
*/
/* // FUCKED LINES
typedef struct
{
char priv[508];
} doomdata_t;
*/ // FUCKED LINES
#define DOOMCOM_ID 0x12345678l
/* // FUCKED LINES
typedef struct
{
long id;
short intnum; // DOOM executes an int to execute commands
// communication between DOOM and the driver
short command; // CMD_SEND or CMD_GET
short remotenode; // dest for send, set by get (-1 = no packet)
short datalength; // bytes in doomdata to be sent
// info common to all nodes
short numnodes; // console is allways node 0
short ticdup; // 1 = no duplication, 2-5 = dup for slow nets
short extratics; // 1 = send a backup tic in every packet
short deathmatch; // 1 = deathmatch
short savegame; // -1 = new game, 0-5 = load savegame
short episode; // 1-3
short map; // 1-9
short skill; // 1-5
// info specific to this node
short consoleplayer;
short numplayers;
short angleoffset; // 1 = left, 0 = center, -1 = right
short drone; // 1 = drone
// packet data to be sent
doomdata_t data;
} doomcom_t;
*/ // FUCKED LINES
extern doomcom_t *doomcom;
/*
====================
=
= I_InitNetwork
=
====================
*/
void I_InitNetwork (void)
{
int i;
i = M_CheckParm ("-net");
if (!i)
{
//
// single player game
//
doomcom = malloc (sizeof (*doomcom) );
memset (doomcom, 0, sizeof(*doomcom) );
netgame = false;
doomcom->id = DOOMCOM_ID;
doomcom->numplayers = doomcom->numnodes = 1;
doomcom->deathmatch = false;
doomcom->consoleplayer = 0;
doomcom->ticdup = 1;
doomcom->extratics = 0;
return;
}
netgame = true;
doomcom = (doomcom_t *)atoi(myargv[i+1]);
//DEBUG
doomcom->skill = startskill;
doomcom->episode = startepisode;
doomcom->map = startmap;
doomcom->deathmatch = deathmatch;
}
void I_NetCmd (void)
{
if (!netgame)
I_Error ("I_NetCmd when not in netgame");
DPMIInt (doomcom->intnum);
}
//=========================================================================
//
// I_CheckExternDriver
//
// Checks to see if a vector, and an address for an external driver
// have been passed.
//=========================================================================
void I_CheckExternDriver(void)
{
int i;
if(!(i = M_CheckParm("-externdriver")))
{
return;
}
i_ExternData = (externdata_t *)atoi(myargv[i+1]);
i_Vector = i_ExternData->vector;
useexterndriver = true;
}
//=========================================================================
//=========================================================================
// Hi-Res (mode 12) stuff
//=========================================================================
//=========================================================================
//==========================================================================
//
// SetVideoModeHR - Set video mode to 640x480x16
//
//==========================================================================
void SetVideoModeHR(void)
{
union REGS regs;
regs.x.eax = 0x12;
int386(VID_INT, ®s, ®s);
}
//==========================================================================
//
// ClearScreenHR - Clear the screen to color 0
//
//==========================================================================
void ClearScreenHR(void)
{
BITPLANE(MASK_PLANE0|MASK_PLANE1|MASK_PLANE2|MASK_PLANE3);
memset((char *)0xa0000,0,38400);
}
//==========================================================================
//
// SlamHR - copy 4-plane buffer to screen
//
//==========================================================================
void SlamHR(char *buffer)
{
BITPLANE(MASK_PLANE0);
memcpy((char *)0xA0000, buffer+P0OFFSET, 38400);
BITPLANE(MASK_PLANE1);
memcpy((char *)0xA0000, buffer+P1OFFSET, 38400);
BITPLANE(MASK_PLANE2);
memcpy((char *)0xA0000, buffer+P2OFFSET, 38400);
BITPLANE(MASK_PLANE3);
memcpy((char *)0xA0000, buffer+P3OFFSET, 38400);
}
//==========================================================================
//
// SlamHR - copy 4-plane buffer to screen
//
// X and Width should be a multiple of 8
// src should be 4 planes of block size, back to back
//==========================================================================
void SlamBlockHR(int x, int y, int w, int h, char *src)
{
int srcwid = w>>3;
char *dest = ((char *)0xA0000) + (y*(640/8)) + (x>>3);
char *dst;
int i;
VB_SYNC;
BITPLANE(MASK_PLANE0);
dst = dest;
for ( i=0; i<h; i++ )
{
memcpy(dst, src, srcwid);
dst += 640/8;
src += srcwid;
}
BITPLANE(MASK_PLANE1);
dst = dest;
for ( i=0; i<h; i++ )
{
memcpy(dst, src, srcwid);
dst += 640/8;
src += srcwid;
}
BITPLANE(MASK_PLANE2);
dst = dest;
for ( i=0; i<h; i++ )
{
memcpy(dst, src, srcwid);
dst += 640/8;
src += srcwid;
}
BITPLANE(MASK_PLANE3);
dst = dest;
for ( i=0; i<h; i++ )
{
memcpy(dst, src, srcwid);
dst += 640/8;
src += srcwid;
}
}
//==========================================================================
//
// InitPaletteHR
//
//==========================================================================
void InitPaletteHR(void)
{
int i;
union REGS regs;
// Set palette registers to point into color registers
for ( i=0; i<16; i++ )
{
regs.x.eax = (0x10<<8)|0x00;
regs.x.ebx = (i<<8)|i;
int386(VID_INT, ®s, ®s);
}
}
//==========================================================================
//
// SetPaletteHR - Set the HR palette
//
//==========================================================================
void SetPaletteHR(byte *palette)
{
int i;
VB_SYNC;
outp(PEL_WRITE_ADR, 0);
for(i = 0; i < 16*3; i++)
{
outp(PEL_DATA, (*palette++));
}
}
//==========================================================================
//
// GetPaletteHR - Get the HR palette
//
//==========================================================================
void GetPaletteHR(byte *palette)
{
int i;
outp(PEL_READ_ADR, 0);
for (i=0; i<16*3; i++)
{
*palette++ = inp(PEL_DATA);
}
}
//==========================================================================
//
// FadeToPaletteHR
//
//==========================================================================
void FadeToPaletteHR(byte *palette)
{
int i,j;
int steps=140; // two-seconds
byte basep[16*3];
byte work[16*3];
int delta;
GetPaletteHR(basep);
for(i = 0; i < steps; i++)
{
for(j = 0; j < 16*3; j++)
{
delta = palette[j]-basep[j];
work[j] = basep[j]+delta*i/steps;
}
SetPaletteHR(work);
}
SetPaletteHR(palette);
}
//==========================================================================
//
// FadeToBlackHR - Fades the palette out to black
//
//==========================================================================
/*
void FadeToBlackHR(void)
{
char work[16*3];
char base[16*3];
int i,j,steps=70;
GetPaletteHR(base);
for (i=0; i<steps; i++)
{
for (j=0; j<16*3; j++)
{
work[j] = base[j]-(base[j]*i/steps);
}
VB_SYNC;
SetPaletteHR(work);
}
memset(work,0,16*3);
SetPaletteHR(work);
}
*/
//==========================================================================
//
// BlackPaletteHR - Instantly blacks out the palette
//
//==========================================================================
void BlackPaletteHR(void)
{
char blackpal[16*3];
memset(blackpal,0,16*3);
SetPaletteHR(blackpal);
}
//==========================================================================
//
//
// I_StartupReadKeys
//
//
//==========================================================================
void I_StartupReadKeys(void)
{
int k;
while (kbdtail < kbdhead)
{
k = keyboardque[kbdtail&(KBDQUESIZE-1)];
kbdtail++;
if (k == 1)
I_Quit ();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -