mirror of
https://github.com/YGGverse/xash3d-fwgs.git
synced 2025-01-30 16:54:29 +00:00
platform: DOS4GW port
This commit is contained in:
parent
fe07c48431
commit
51849c6140
127
engine/platform/dos/in_dos.c
Normal file
127
engine/platform/dos/in_dos.c
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
/*
|
||||||
|
in_dos.c - DOS input
|
||||||
|
Copyright (C) 2020 mittorn
|
||||||
|
|
||||||
|
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 3 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.
|
||||||
|
*/
|
||||||
|
#include "platform/platform.h"
|
||||||
|
#include "input.h"
|
||||||
|
#include <dos.h>
|
||||||
|
|
||||||
|
static struct key_s
|
||||||
|
{
|
||||||
|
byte buf[256];
|
||||||
|
byte buf_head;
|
||||||
|
qboolean shift;
|
||||||
|
qboolean chars;
|
||||||
|
} keystate;
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
|
||||||
|
byte scantokey[128] =
|
||||||
|
{
|
||||||
|
// 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', '-', '=', K_BACKSPACE, 9, // 0
|
||||||
|
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i',
|
||||||
|
'o', 'p', '[', ']', 13 , K_CTRL,'a', 's', // 1
|
||||||
|
'd', 'f', 'g', 'h', 'j', 'k', 'l', ';',
|
||||||
|
'\'' , '`', K_SHIFT,'\\', 'z', 'x', 'c', 'v', // 2
|
||||||
|
'b', 'n', 'm', ',', '.', '/', K_SHIFT,'*',
|
||||||
|
K_ALT,' ', 0 , K_F1, K_F2, K_F3, K_F4, K_F5, // 3
|
||||||
|
K_F6, K_F7, K_F8, K_F9, K_F10,0 , 0 , K_HOME,
|
||||||
|
K_UPARROW,K_PGUP,'-',K_LEFTARROW,'5',K_RIGHTARROW,'+',K_END, //4
|
||||||
|
K_DOWNARROW,K_PGDN,K_INS,K_DEL,0,0, 0, K_F11,
|
||||||
|
K_F12,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
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// will be implemented later
|
||||||
|
void Platform_RunEvents( void )
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for( i = 0; i < keystate.buf_head;i++ )
|
||||||
|
{
|
||||||
|
int k = keystate.buf[i];
|
||||||
|
int key = scantokey[k&0x7f];
|
||||||
|
int value = !(k & 0x80);
|
||||||
|
|
||||||
|
Key_Event( key , value );
|
||||||
|
|
||||||
|
if( keystate.chars && value )
|
||||||
|
{
|
||||||
|
if( key >= 32 && key < 127 )
|
||||||
|
{
|
||||||
|
if( keystate.shift )
|
||||||
|
{
|
||||||
|
key = Key_ToUpper( key );
|
||||||
|
}
|
||||||
|
CL_CharEvent( key );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( key == K_SHIFT )
|
||||||
|
keystate.shift = value;
|
||||||
|
}
|
||||||
|
keystate.buf_head = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void GAME_EXPORT Platform_GetMousePos( int *x, int *y )
|
||||||
|
{
|
||||||
|
*x = *y = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GAME_EXPORT Platform_SetMousePos(int x, int y)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int Platform_JoyInit( int numjoy )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Platform_EnableTextInput( qboolean enable )
|
||||||
|
{
|
||||||
|
keystate.chars = enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Platform_PreCreateMove( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Platform_MouseMove( float *x, float *y )
|
||||||
|
{
|
||||||
|
static int lx,ly;
|
||||||
|
union REGS regs;
|
||||||
|
|
||||||
|
regs.w.ax = regs.w.bx = regs.w.cx = regs.w.dx = 0;
|
||||||
|
|
||||||
|
regs.w.ax = 11;
|
||||||
|
int386(0x33,®s,®s);
|
||||||
|
*x = (short)regs.w.cx, *y = (short)regs.w.dx;
|
||||||
|
regs.w.ax = regs.w.bx = regs.w.cx = regs.w.dx = 0;
|
||||||
|
int386(0x33,®s,®s);// reset
|
||||||
|
}
|
||||||
|
|
||||||
|
void __interrupt __far keyhandler( void )
|
||||||
|
{
|
||||||
|
keystate.buf[keystate.buf_head++] = inp(0x60);
|
||||||
|
outp(0x20, 0x20);
|
||||||
|
}
|
13
engine/platform/dos/ld.sh
Executable file
13
engine/platform/dos/ld.sh
Executable file
@ -0,0 +1,13 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
out1=$2
|
||||||
|
shift 2
|
||||||
|
out=$1
|
||||||
|
shift 1
|
||||||
|
|
||||||
|
echo $* > $out
|
||||||
|
rm -r $out.files
|
||||||
|
mkdir $out.files
|
||||||
|
cp --parents $* $out.files/
|
||||||
|
echo cp --parents $* $out.files/
|
||||||
|
|
||||||
|
#exit 0
|
7
engine/platform/dos/objcopy.sh
Executable file
7
engine/platform/dos/objcopy.sh
Executable file
@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
cd $3.files
|
||||||
|
objxdef $(cat $3) |grep -v _lib_> syms.tmp
|
||||||
|
objchg -m=$2_* -s=syms.tmp $(cat $3)
|
||||||
|
wlib $3.a $(cat $3)
|
||||||
|
cp $3.a $4
|
||||||
|
cd ..
|
117
engine/platform/dos/sys_dos.c
Normal file
117
engine/platform/dos/sys_dos.c
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
/*
|
||||||
|
sys_dos.c - dos timer
|
||||||
|
Copyright (C) 2020 mittorn
|
||||||
|
|
||||||
|
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 3 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "platform/platform.h"
|
||||||
|
#include <dos.h>
|
||||||
|
void Platform_GetClipboardText( char *buffer, size_t size )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Platform_SetClipboardText( const char *buffer, size_t size )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void *Platform_GetNativeObject( const char *name )
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Platform_Vibrate(float life, char flags)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Platform_ShellExecute( const char *path, const char *parms )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
volatile int ticks=0;
|
||||||
|
|
||||||
|
#if XASH_TIMER == TIMER_DOS
|
||||||
|
double Platform_DoubleTime( void )
|
||||||
|
{
|
||||||
|
return 0.005*ticks;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Platform_Sleep( int msec )
|
||||||
|
{
|
||||||
|
//usleep( msec * 1000 );
|
||||||
|
}
|
||||||
|
#endif // XASH_TIMER == TIMER_DOS
|
||||||
|
#define PIT_FREQUENCY 0x1234DDL
|
||||||
|
#define frequency 140
|
||||||
|
#define counter PIT_FREQUENCY/frequency
|
||||||
|
|
||||||
|
volatile int BIOS_ticks=0;
|
||||||
|
volatile int second_ticks=0;
|
||||||
|
volatile int second_flag=0;
|
||||||
|
|
||||||
|
|
||||||
|
static void (__interrupt __far *orig_int_1c)();
|
||||||
|
static void (__interrupt __far *orig_int_09)();
|
||||||
|
|
||||||
|
|
||||||
|
static void __interrupt __far timerhandler()
|
||||||
|
{
|
||||||
|
BIOS_ticks += counter;
|
||||||
|
second_ticks++, ticks++;
|
||||||
|
|
||||||
|
if( BIOS_ticks >= 0x10000 )
|
||||||
|
{
|
||||||
|
BIOS_ticks = 0;
|
||||||
|
_chain_intr( orig_int_1c );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( second_ticks>=frequency )
|
||||||
|
{
|
||||||
|
second_flag = 1;
|
||||||
|
second_ticks = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
outp( 0x20, 0x20 );
|
||||||
|
}
|
||||||
|
|
||||||
|
// in_dos.c
|
||||||
|
extern void __interrupt __far keyhandler( void );
|
||||||
|
|
||||||
|
void Platform_Init( void )
|
||||||
|
{
|
||||||
|
// save original vectors
|
||||||
|
orig_int_1c = _dos_getvect( 0x1c );
|
||||||
|
orig_int_09 = _dos_getvect( 0x09 );
|
||||||
|
_dos_setvect( 0x1c, timerhandler );
|
||||||
|
_dos_setvect( 0x09, keyhandler );
|
||||||
|
|
||||||
|
// set clock freq
|
||||||
|
outp( 0x43, 0x34 );
|
||||||
|
outp( 0x40, (char)(counter%256) );
|
||||||
|
outp( 0x40, (char)(counter/256) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Platform_Shutdown( void )
|
||||||
|
{
|
||||||
|
// restore freq
|
||||||
|
outp( 0x43, 0x34 );
|
||||||
|
outp( 0x40, 0 );
|
||||||
|
outp( 0x40, 0 );
|
||||||
|
|
||||||
|
//restore vectors
|
||||||
|
_dos_setvect( 0x1c, orig_int_1c );
|
||||||
|
_dos_setvect( 0x09, orig_int_09 );
|
||||||
|
}
|
550
engine/platform/dos/vid_dos.c
Normal file
550
engine/platform/dos/vid_dos.c
Normal file
@ -0,0 +1,550 @@
|
|||||||
|
/*
|
||||||
|
vid_dos.c - DOS VGA/VESA driver
|
||||||
|
Copyright (C) 2020 mittorn
|
||||||
|
|
||||||
|
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 3 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "platform/platform.h"
|
||||||
|
#if XASH_VIDEO == VIDEO_DOS
|
||||||
|
#include "input.h"
|
||||||
|
#include "client.h"
|
||||||
|
#include "filesystem.h"
|
||||||
|
#include "vid_common.h"
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <dos.h>
|
||||||
|
#include <i86.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
Android_SwapBuffers
|
||||||
|
|
||||||
|
Update screen. Use native EGL if possible
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
void GL_SwapBuffers( void )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DOS_GetScreenRes( int *x, int *y )
|
||||||
|
{
|
||||||
|
*x = 320;
|
||||||
|
*y = 200;
|
||||||
|
}
|
||||||
|
|
||||||
|
qboolean R_Init_Video( const int type )
|
||||||
|
{
|
||||||
|
qboolean retval;
|
||||||
|
|
||||||
|
VID_StartupGamma();
|
||||||
|
|
||||||
|
if( type != REF_SOFTWARE )
|
||||||
|
return false; /// glide???
|
||||||
|
|
||||||
|
if( !(retval = VID_SetMode()) )
|
||||||
|
{
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
host.renderinfo_changed = false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void R_Free_Video( void )
|
||||||
|
{
|
||||||
|
// restore text mode
|
||||||
|
union REGS regs;
|
||||||
|
regs.w.ax = 3;
|
||||||
|
int386(0x10,®s,®s);
|
||||||
|
|
||||||
|
ref.dllFuncs.GL_ClearExtensions();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
qboolean VID_SetMode( void )
|
||||||
|
{
|
||||||
|
R_ChangeDisplaySettings( 0, 0, false ); // width and height are ignored anyway
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
rserr_t R_ChangeDisplaySettings( int width, int height, qboolean fullscreen )
|
||||||
|
{
|
||||||
|
int render_w, render_h;
|
||||||
|
uint rotate = vid_rotate->value;
|
||||||
|
|
||||||
|
DOS_GetScreenRes( &width, &height );
|
||||||
|
|
||||||
|
render_w = width;
|
||||||
|
render_h = height;
|
||||||
|
|
||||||
|
Con_Reportf( "R_ChangeDisplaySettings: forced resolution to %dx%d)\n", width, height );
|
||||||
|
|
||||||
|
if( ref.dllFuncs.R_SetDisplayTransform( rotate, 0, 0, vid_scale->value, vid_scale->value ) )
|
||||||
|
{
|
||||||
|
if( rotate & 1 )
|
||||||
|
{
|
||||||
|
int swap = render_w;
|
||||||
|
|
||||||
|
render_w = render_h;
|
||||||
|
render_h = swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
render_h /= vid_scale->value;
|
||||||
|
render_w /= vid_scale->value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Con_Printf( S_WARN "failed to setup screen transform\n" );
|
||||||
|
}
|
||||||
|
R_SaveVideoMode( width, height, render_w, render_h );
|
||||||
|
|
||||||
|
return rserr_ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GL_SetAttribute( int attr, int val )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GL_GetAttribute( int attr, int *val )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int R_MaxVideoModes( void )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
vidmode_t* R_GetVideoMode( int num )
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* GL_GetProcAddress( const char *name ) // RenderAPI requirement
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static qboolean vsync;
|
||||||
|
|
||||||
|
void GL_UpdateSwapInterval( void )
|
||||||
|
{
|
||||||
|
// disable VSync while level is loading
|
||||||
|
if( cls.state < ca_active )
|
||||||
|
{
|
||||||
|
// setup vsync here
|
||||||
|
vsync = false;
|
||||||
|
SetBits( gl_vsync->flags, FCVAR_CHANGED );
|
||||||
|
}
|
||||||
|
else if( FBitSet( gl_vsync->flags, FCVAR_CHANGED ))
|
||||||
|
{
|
||||||
|
ClearBits( gl_vsync->flags, FCVAR_CHANGED );
|
||||||
|
vsync = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
================================
|
||||||
|
|
||||||
|
VESA structures
|
||||||
|
|
||||||
|
================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct RealPointer
|
||||||
|
{
|
||||||
|
short Segment; //The real mode segment (offset is 0).
|
||||||
|
short Selector; //In protected mode, you need to chuck this dude into a segment register and use an offset 0.
|
||||||
|
} RealPointer;
|
||||||
|
|
||||||
|
typedef struct VesaInfo
|
||||||
|
{
|
||||||
|
char Signature[4];
|
||||||
|
short Version;
|
||||||
|
short OEMNameOffset;
|
||||||
|
short OEMNameSegment; //Pointer to OEM name?
|
||||||
|
char Capabilities[4];
|
||||||
|
short SupportedModesOffset;
|
||||||
|
short SupportedModesSegment; //Pointer to list of supported VESA and OEM modes (terminated with 0xffff).
|
||||||
|
char Reserved[238];
|
||||||
|
} VesaInfo;
|
||||||
|
|
||||||
|
typedef struct VesaModeData
|
||||||
|
{
|
||||||
|
short ModeAttributes;
|
||||||
|
char WindowAAttributes;
|
||||||
|
char WindowBAttributes;
|
||||||
|
short WindowGranularity;
|
||||||
|
short WindowSize;
|
||||||
|
short StartSegmentWindowA;
|
||||||
|
short StartSegmentWindowB;
|
||||||
|
void (*WindowPositioningFunction)(int page);
|
||||||
|
short BytesPerScanLine;
|
||||||
|
|
||||||
|
//Remainder of this structure is optional for VESA modes in v1.0/1.1, needed for OEM modes.
|
||||||
|
|
||||||
|
short PixelWidth;
|
||||||
|
short PixelHeight;
|
||||||
|
char CharacterCellPixelWidth;
|
||||||
|
char CharacterCellPixelHeight;
|
||||||
|
char NumberOfMemoryPlanes;
|
||||||
|
char BitsPerPixel;
|
||||||
|
char NumberOfBanks;
|
||||||
|
char MemoryModelType;
|
||||||
|
char SizeOfBank;
|
||||||
|
char NumberOfImagePages;
|
||||||
|
char Reserved1;
|
||||||
|
|
||||||
|
//VBE v1.2+
|
||||||
|
|
||||||
|
char RedMaskSize;
|
||||||
|
char RedFieldPosition;
|
||||||
|
char GreenMaskSize;
|
||||||
|
char GreenFieldPosition;
|
||||||
|
char BlueMaskSize;
|
||||||
|
char BlueFieldPosition;
|
||||||
|
char ReservedMaskSize;
|
||||||
|
char ReservedFieldPosition;
|
||||||
|
char DirectColourModeInfo;
|
||||||
|
char Reserved2[216];
|
||||||
|
} VesaModeData;
|
||||||
|
|
||||||
|
typedef struct RMREGS
|
||||||
|
{
|
||||||
|
int edi;
|
||||||
|
int esi;
|
||||||
|
int ebp;
|
||||||
|
int reserved;
|
||||||
|
int ebx;
|
||||||
|
int edx;
|
||||||
|
int ecx;
|
||||||
|
int eax;
|
||||||
|
short flags;
|
||||||
|
short es,ds,fs,gs,ip,cs,sp,ss;
|
||||||
|
} RMREGS;
|
||||||
|
|
||||||
|
static VesaInfo far *vesa_info = NULL;
|
||||||
|
static VesaModeData far *vesa_mode_data = NULL;
|
||||||
|
static int vesa_granularity;
|
||||||
|
static int vesa_page;
|
||||||
|
static int vesa_width;
|
||||||
|
static int vesa_height;
|
||||||
|
static int vesa_bits_per_pixel;
|
||||||
|
|
||||||
|
static RealPointer vesa_info_rp;
|
||||||
|
static RealPointer vesa_mode_data_rp;
|
||||||
|
|
||||||
|
|
||||||
|
static void far *allocate_dos_memory( RealPointer * rp,int bytes_to_allocate )
|
||||||
|
{
|
||||||
|
void far *ptr = NULL;
|
||||||
|
union REGS regs;
|
||||||
|
|
||||||
|
bytes_to_allocate = ((bytes_to_allocate + 15) & 0xfffffff0); //Round up to nearest paragraph.
|
||||||
|
memset(®s,0,sizeof(regs));
|
||||||
|
regs.w.ax = 0x100;
|
||||||
|
regs.w.bx = (short)(bytes_to_allocate >> 4); //Allocate dos memory in pages, so convert bytes to pages.
|
||||||
|
int386(0x31,®s,®s);
|
||||||
|
if(regs.x.cflag == 0)
|
||||||
|
{ //Everything OK.
|
||||||
|
rp->Segment = regs.w.ax;
|
||||||
|
rp->Selector = regs.w.dx;
|
||||||
|
ptr = MK_FP(regs.w.dx,0);
|
||||||
|
}
|
||||||
|
return(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
/* Free an area of DOS memory. */
|
||||||
|
/****************************************************************************/
|
||||||
|
|
||||||
|
static void free_dos_memory( RealPointer * rp )
|
||||||
|
{
|
||||||
|
union REGS regs;
|
||||||
|
|
||||||
|
regs.w.ax = 0x101;
|
||||||
|
regs.w.dx = rp->Selector;
|
||||||
|
int386(0x31,®s,®s);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
/* Get information about the VESA driver. */
|
||||||
|
/* */
|
||||||
|
/* Returns: */
|
||||||
|
/* TRUE - VESA driver present. vesa_info set to point to a */
|
||||||
|
/* a structure containing capability info etc. */
|
||||||
|
/* FALSE - No VESA driver. */
|
||||||
|
/* */
|
||||||
|
/****************************************************************************/
|
||||||
|
|
||||||
|
static int vesa_get_info( void )
|
||||||
|
{
|
||||||
|
union REGS regs;
|
||||||
|
struct SREGS sregs;
|
||||||
|
RMREGS rmregs;
|
||||||
|
int ok = 0;
|
||||||
|
|
||||||
|
if((vesa_info = (VesaInfo far *)allocate_dos_memory(&vesa_info_rp,sizeof(VesaInfo))) != NULL)
|
||||||
|
{
|
||||||
|
memset(&rmregs,0,sizeof(rmregs));
|
||||||
|
memset(®s,0,sizeof(regs));
|
||||||
|
memset(&sregs,0,sizeof(sregs));
|
||||||
|
segread(&sregs);
|
||||||
|
rmregs.eax = 0x4f00;
|
||||||
|
rmregs.es = vesa_info_rp.Segment;
|
||||||
|
rmregs.ds = vesa_info_rp.Segment;
|
||||||
|
regs.x.eax = 0x300;
|
||||||
|
regs.x.ebx = 0x10;
|
||||||
|
regs.x.ecx = 0;
|
||||||
|
sregs.es = FP_SEG(&rmregs);
|
||||||
|
regs.x.edi = FP_OFF(&rmregs);
|
||||||
|
int386x(0x31,®s,®s,&sregs); //Get vesa info.
|
||||||
|
|
||||||
|
if(rmregs.eax == 0x4f) ok=1;
|
||||||
|
}
|
||||||
|
return(ok);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
/* Free the information allocated with vesa_get_info() */
|
||||||
|
/****************************************************************************/
|
||||||
|
|
||||||
|
static int vesa_free_info( void )
|
||||||
|
{
|
||||||
|
free_dos_memory( &vesa_info_rp );
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
/* Get VESA mode information. Information is loaded into vesa_mode_data. */
|
||||||
|
/* vesa_get_info() must be called before calling this function. */
|
||||||
|
/* Should error check this really. */
|
||||||
|
/* */
|
||||||
|
/* Inputs: */
|
||||||
|
/* vmode - The mode that you wish to get information about. */
|
||||||
|
/* */
|
||||||
|
/* Returns: */
|
||||||
|
/* TRUE - vesa_mode_data points to a filled VesaModeData structure. */
|
||||||
|
/* FALSE - vesa_mode_data probably invalid. Mode probably not */
|
||||||
|
/* supported. */
|
||||||
|
/* */
|
||||||
|
/****************************************************************************/
|
||||||
|
|
||||||
|
static int vesa_get_mode_info( short vmode )
|
||||||
|
{
|
||||||
|
union REGS regs;
|
||||||
|
struct SREGS sregs;
|
||||||
|
RMREGS rmregs;
|
||||||
|
int ok=0;
|
||||||
|
|
||||||
|
if((vesa_mode_data = (VesaModeData far *)allocate_dos_memory(&vesa_mode_data_rp,sizeof(VesaModeData))) != NULL)
|
||||||
|
{
|
||||||
|
memset(&rmregs,0,sizeof(rmregs));
|
||||||
|
rmregs.es = vesa_mode_data_rp.Segment;
|
||||||
|
rmregs.ds = vesa_mode_data_rp.Segment;
|
||||||
|
rmregs.edi = 0;
|
||||||
|
rmregs.eax = 0x4f01;
|
||||||
|
rmregs.ecx = vmode;
|
||||||
|
memset(®s,0,sizeof(regs));
|
||||||
|
memset(&sregs,0,sizeof(sregs));
|
||||||
|
segread(&sregs);
|
||||||
|
regs.x.eax = 0x300;
|
||||||
|
regs.x.ebx = 0x10;
|
||||||
|
regs.x.edi = (int)&rmregs;
|
||||||
|
int386x(0x31,®s,®s,&sregs);
|
||||||
|
if(regs.h.al == 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
//cache a few important items in protected mode memory area.
|
||||||
|
|
||||||
|
vesa_granularity = vesa_mode_data->WindowGranularity;
|
||||||
|
vesa_width = vesa_mode_data->PixelWidth;
|
||||||
|
vesa_height = vesa_mode_data->PixelHeight;
|
||||||
|
vesa_bits_per_pixel = vesa_mode_data->BitsPerPixel;
|
||||||
|
ok = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(ok);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
/* Set the current vesa screen page. */
|
||||||
|
/* */
|
||||||
|
/* Inputs: */
|
||||||
|
/* vpage - Page number to set. */
|
||||||
|
/* */
|
||||||
|
/****************************************************************************/
|
||||||
|
|
||||||
|
static void vesa_set_page( int vpage )
|
||||||
|
{
|
||||||
|
union REGS regs;
|
||||||
|
|
||||||
|
vesa_page = vpage;
|
||||||
|
regs.w.ax = 0x4f05;
|
||||||
|
regs.w.bx = 0;
|
||||||
|
regs.w.cx = 0;
|
||||||
|
regs.w.dx = (short)(vpage == 0 ? 0 : (short)((vpage * 64) / vesa_granularity));
|
||||||
|
int386(0x10,®s,®s);
|
||||||
|
regs.w.ax = 0x4f05;
|
||||||
|
regs.w.bx = 1;
|
||||||
|
regs.w.cx = 0;
|
||||||
|
regs.w.dx = (short)(vpage == 0 ? 0 : (short)((vpage * 64) / vesa_granularity));
|
||||||
|
int386(0x10,®s,®s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
/* Set VESA video mode. You MUST have previously called vesa_get_info(). */
|
||||||
|
/* */
|
||||||
|
/* Inputs: */
|
||||||
|
/* vmode - The VESA mode that you want. e.g. 0x101 is 640x480 256 */
|
||||||
|
/* colours. */
|
||||||
|
/* */
|
||||||
|
/* Returns: */
|
||||||
|
/* TRUE - The mode has been set. */
|
||||||
|
/* FALSE - The mode has not been set, probably not supported. */
|
||||||
|
/* */
|
||||||
|
/****************************************************************************/
|
||||||
|
|
||||||
|
int vesa_set_mode( short vmode )
|
||||||
|
{
|
||||||
|
union REGS regs;
|
||||||
|
int ok=0;
|
||||||
|
|
||||||
|
memset(®s,0,sizeof(regs));
|
||||||
|
regs.w.ax = 0x4f02;
|
||||||
|
regs.w.bx = vmode;
|
||||||
|
int386(0x10,®s,®s);
|
||||||
|
if(regs.w.ax == 0x004f)
|
||||||
|
{
|
||||||
|
vesa_get_mode_info(vmode);
|
||||||
|
vesa_set_page(0); //Probably not needed, but here for completeness.
|
||||||
|
ok = 1;
|
||||||
|
}
|
||||||
|
return(ok);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
/* Free the info previously allocated with vesa_get_info() */
|
||||||
|
/****************************************************************************/
|
||||||
|
|
||||||
|
void vesa_free_mode_info( void )
|
||||||
|
{
|
||||||
|
free_dos_memory(&vesa_mode_data_rp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_13h( void )
|
||||||
|
{
|
||||||
|
int r, g, b;
|
||||||
|
union REGS regs;
|
||||||
|
|
||||||
|
// set 13h vga mode
|
||||||
|
memset(®s,0,sizeof(regs));
|
||||||
|
regs.w.ax = 0x13;
|
||||||
|
int386(0x10,®s,®s);
|
||||||
|
|
||||||
|
// set 332 palette
|
||||||
|
outp(0x3c8, 0);
|
||||||
|
for (r=0; r<8; r++)
|
||||||
|
for (b=0; b<4; b++)
|
||||||
|
for (g=0; g<8; g++)
|
||||||
|
{
|
||||||
|
outp(0x3c9, (b<<4)+8);
|
||||||
|
outp(0x3c9, (g<<3)+4);
|
||||||
|
outp(0x3c9, (r<<3)+4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void waitvbl()
|
||||||
|
{
|
||||||
|
while (!(inp (0x3da) & 8)) {}
|
||||||
|
while (inp (0x3da) & 8) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static byte *fb;
|
||||||
|
|
||||||
|
void *SW_LockBuffer( void )
|
||||||
|
{
|
||||||
|
return fb;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SW_UnlockBuffer( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
int left = 320*200*2;
|
||||||
|
int done = 0;
|
||||||
|
int vpage = 0;
|
||||||
|
|
||||||
|
if( vsync )
|
||||||
|
waitvbl();
|
||||||
|
|
||||||
|
// no separate fb
|
||||||
|
if( fb == 0xa0000 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
while( left )
|
||||||
|
{
|
||||||
|
int flip = left;
|
||||||
|
|
||||||
|
if( flip > 65536 )
|
||||||
|
flip = 65536;
|
||||||
|
|
||||||
|
vesa_set_page(vpage);
|
||||||
|
memcpy((void *)0xa0000, fb+done, flip);
|
||||||
|
|
||||||
|
done += flip;
|
||||||
|
left -= flip;
|
||||||
|
vpage++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define FB_BF_TO_MASK(x) (((1 << x.length) - 1) << (x.offset))
|
||||||
|
|
||||||
|
qboolean SW_CreateBuffer( int width, int height, uint *stride, uint *bpp, uint *r, uint *g, uint *b )
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
*stride = 320;
|
||||||
|
|
||||||
|
vesa_get_info();
|
||||||
|
|
||||||
|
if( !Sys_CheckParm("-novesa") && vesa_set_mode( 0x10E ) )
|
||||||
|
{
|
||||||
|
fb = malloc( 320*200*2 );
|
||||||
|
*bpp = 2;
|
||||||
|
*b = 31;
|
||||||
|
*g = 63 << 5;
|
||||||
|
*r = 31 << 11;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// fallback to 256 color
|
||||||
|
*b = 2 << 6;
|
||||||
|
*g = 7 << 0;
|
||||||
|
*r = 7 << 3;
|
||||||
|
*bpp = 1;
|
||||||
|
init_13h();
|
||||||
|
fb = 0xa0000;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -36,6 +36,11 @@ def configure(conf):
|
|||||||
if conf.env.DEST_OS == 'linux':
|
if conf.env.DEST_OS == 'linux':
|
||||||
conf.check_cc(lib='rt')
|
conf.check_cc(lib='rt')
|
||||||
conf.define('XASH_DEDICATED', 1)
|
conf.define('XASH_DEDICATED', 1)
|
||||||
|
elif conf.env.DEST_OS == 'dos':
|
||||||
|
conf.options.STATIC = True
|
||||||
|
conf.options.NO_ASYNC_RESOLVE = True
|
||||||
|
if not conf.check_cc( fragment='int main(){ int i = socket();}', lib = 'wattcpwl', mandatory=False ):
|
||||||
|
conf.define('XASH_NO_NETWORK',1)
|
||||||
elif conf.env.DEST_OS == 'android': # Android doesn't need SDL2
|
elif conf.env.DEST_OS == 'android': # Android doesn't need SDL2
|
||||||
for i in ['android', 'log', 'EGL']:
|
for i in ['android', 'log', 'EGL']:
|
||||||
conf.check_cc(lib = i)
|
conf.check_cc(lib = i)
|
||||||
@ -91,18 +96,23 @@ def build(bld):
|
|||||||
'server/*.c'])
|
'server/*.c'])
|
||||||
|
|
||||||
# basic build: dedicated only, no dependencies
|
# basic build: dedicated only, no dependencies
|
||||||
if bld.env.DEST_OS != 'win32':
|
if bld.env.DEST_OS == 'win32':
|
||||||
|
libs += ['USER32', 'SHELL32', 'GDI32', 'ADVAPI32', 'DBGHELP', 'PSAPI', 'WS2_32' ]
|
||||||
|
source += bld.path.ant_glob(['platform/win32/*.c'])
|
||||||
|
elif bld.env.DEST_OS != 'dos': #posix
|
||||||
libs += [ 'M', 'RT', 'PTHREAD', 'ASOUND']
|
libs += [ 'M', 'RT', 'PTHREAD', 'ASOUND']
|
||||||
if not bld.env.STATIC:
|
if not bld.env.STATIC:
|
||||||
libs += ['DL']
|
libs += ['DL']
|
||||||
source += bld.path.ant_glob(['platform/posix/*.c'])
|
source += bld.path.ant_glob(['platform/posix/*.c'])
|
||||||
else:
|
|
||||||
libs += ['USER32', 'SHELL32', 'GDI32', 'ADVAPI32', 'DBGHELP', 'PSAPI', 'WS2_32' ]
|
|
||||||
source += bld.path.ant_glob(['platform/win32/*.c'])
|
|
||||||
|
|
||||||
if bld.env.DEST_OS == 'linux':
|
if bld.env.DEST_OS == 'linux':
|
||||||
source += bld.path.ant_glob(['platform/linux/*.c'])
|
source += bld.path.ant_glob(['platform/linux/*.c'])
|
||||||
|
|
||||||
|
if bld.env.DEST_OS == 'dos':
|
||||||
|
source += bld.path.ant_glob(['platform/dos/*.c'])
|
||||||
|
source += bld.path.ant_glob(['platform/stub/s_stub.c'])
|
||||||
|
|
||||||
|
|
||||||
if bld.get_define('XASH_CUSTOM_SWAP'):
|
if bld.get_define('XASH_CUSTOM_SWAP'):
|
||||||
source += bld.path.ant_glob(['platform/misc/kmalloc.c', 'platform/misc/sbrk.c'])
|
source += bld.path.ant_glob(['platform/misc/kmalloc.c', 'platform/misc/sbrk.c'])
|
||||||
|
|
||||||
|
10
wscript
10
wscript
@ -211,7 +211,8 @@ def configure(conf):
|
|||||||
# disable thread-safe local static initialization for C++11 code, as it cause crashes on Windows XP
|
# disable thread-safe local static initialization for C++11 code, as it cause crashes on Windows XP
|
||||||
'msvc': ['/D_USING_V110_SDK71_', '/Zi', '/FS', '/Zc:threadSafeInit-', '/MT'],
|
'msvc': ['/D_USING_V110_SDK71_', '/Zi', '/FS', '/Zc:threadSafeInit-', '/MT'],
|
||||||
'clang': ['-g', '-gdwarf-2', '-fvisibility=hidden'],
|
'clang': ['-g', '-gdwarf-2', '-fvisibility=hidden'],
|
||||||
'gcc': ['-g', '-fvisibility=hidden']
|
'gcc': ['-g', '-fvisibility=hidden'],
|
||||||
|
'owcc': ['-fno-short-enum', '-ffloat-store', '-g3']
|
||||||
},
|
},
|
||||||
'fast': {
|
'fast': {
|
||||||
'msvc': ['/O2', '/Oy'],
|
'msvc': ['/O2', '/Oy'],
|
||||||
@ -230,11 +231,13 @@ def configure(conf):
|
|||||||
},
|
},
|
||||||
'release': {
|
'release': {
|
||||||
'msvc': ['/O2'],
|
'msvc': ['/O2'],
|
||||||
|
'owcc': ['-O3', '-foptimize-sibling-calls', '-fomit-leaf-frame-pointer', '-fomit-frame-pointer', '-fschedule-insns', '-funsafe-math-optimizations', '-funroll-loops', '-frerun-optimizer', '-finline-functions', '-finline-limit=512', '-fguess-branch-probability', '-fno-strict-aliasing', '-floop-optimize'],
|
||||||
'default': ['-O3']
|
'default': ['-O3']
|
||||||
},
|
},
|
||||||
'debug': {
|
'debug': {
|
||||||
'msvc': ['/O1'],
|
'msvc': ['/O1'],
|
||||||
'gcc': ['-Og'],
|
'gcc': ['-Og'],
|
||||||
|
'owcc': ['-O0', '-fno-omit-frame-pointer', '-funwind-tables', '-fno-omit-leaf-frame-pointer'],
|
||||||
'default': ['-O1']
|
'default': ['-O1']
|
||||||
},
|
},
|
||||||
'sanitize': {
|
'sanitize': {
|
||||||
@ -276,7 +279,8 @@ def configure(conf):
|
|||||||
'-Werror=old-style-declaration',
|
'-Werror=old-style-declaration',
|
||||||
'-Werror=old-style-definition',
|
'-Werror=old-style-definition',
|
||||||
'-Werror=declaration-after-statement',
|
'-Werror=declaration-after-statement',
|
||||||
'-Werror=enum-conversion'
|
'-Werror=enum-conversion',
|
||||||
|
'-fnonconst-initializers' # owcc
|
||||||
]
|
]
|
||||||
|
|
||||||
linkflags = conf.get_flags_by_type(linker_flags, conf.options.BUILD_TYPE, conf.env.COMPILER_CC, conf.env.CC_VERSION[0])
|
linkflags = conf.get_flags_by_type(linker_flags, conf.options.BUILD_TYPE, conf.env.COMPILER_CC, conf.env.CC_VERSION[0])
|
||||||
@ -337,6 +341,8 @@ def configure(conf):
|
|||||||
|
|
||||||
conf.env.DEDICATED = conf.options.DEDICATED
|
conf.env.DEDICATED = conf.options.DEDICATED
|
||||||
conf.env.SINGLE_BINARY = conf.options.SINGLE_BINARY or conf.env.DEDICATED
|
conf.env.SINGLE_BINARY = conf.options.SINGLE_BINARY or conf.env.DEDICATED
|
||||||
|
if conf.env.DEST_OS == 'dos':
|
||||||
|
conf.env.SINGLE_BINARY = True
|
||||||
|
|
||||||
if conf.env.DEST_OS != 'win32':
|
if conf.env.DEST_OS != 'win32':
|
||||||
conf.check_cc(lib='dl', mandatory=False)
|
conf.check_cc(lib='dl', mandatory=False)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user