2006-04-23 06:44:19 +00:00
# include "compat.h"
# include "osd.h"
# include "build.h"
# include "baselayer.h"
# ifdef RENDERTYPEWIN
# include "winlayer.h"
# endif
2009-08-09 05:32:17 +00:00
# include "polymost.h"
2010-05-25 10:56:00 +00:00
// input
char inputdevices = 0 ;
char keystatus [ 256 ] , keyfifo [ KEYFIFOSIZ ] , keyfifoplc , keyfifoend ;
char keyasciififo [ KEYFIFOSIZ ] , keyasciififoplc , keyasciififoend ;
char remap [ 256 ] ;
int32_t remapinit = 0 ;
char key_names [ 256 ] [ 24 ] ;
volatile int32_t mousex = 0 , mousey = 0 , mouseb = 0 ;
2011-04-07 01:16:29 +00:00
volatile uint8_t moustat = 0 , mousegrab = 0 ;
2010-05-25 10:56:00 +00:00
int32_t * joyaxis = NULL , joyb = 0 , * joyhat = NULL ;
char joyisgamepad = 0 , joynumaxes = 0 , joynumbuttons = 0 , joynumhats = 0 ;
int32_t joyaxespresent = 0 ;
void ( * keypresscallback ) ( int32_t , int32_t ) = 0 ;
void ( * mousepresscallback ) ( int32_t , int32_t ) = 0 ;
void ( * joypresscallback ) ( int32_t , int32_t ) = 0 ;
2010-11-27 22:12:24 +00:00
void ( * after_handleevents_hook ) ( void ) = 0 ;
2010-05-25 10:56:00 +00:00
2010-07-03 08:53:57 +00:00
extern int16_t brightness ;
2010-05-25 10:56:00 +00:00
//
// set{key|mouse|joy}presscallback() -- sets a callback which gets notified when keys are pressed
//
void setkeypresscallback ( void ( * callback ) ( int32_t , int32_t ) ) { keypresscallback = callback ; }
void setmousepresscallback ( void ( * callback ) ( int32_t , int32_t ) ) { mousepresscallback = callback ; }
void setjoypresscallback ( void ( * callback ) ( int32_t , int32_t ) ) { joypresscallback = callback ; }
2008-07-02 01:32:53 +00:00
char scantoasc [ 128 ] =
{
0 , 0 , ' 1 ' , ' 2 ' , ' 3 ' , ' 4 ' , ' 5 ' , ' 6 ' , ' 7 ' , ' 8 ' , ' 9 ' , ' 0 ' , ' - ' , ' = ' , 0 , 0 ,
' q ' , ' w ' , ' e ' , ' r ' , ' t ' , ' y ' , ' u ' , ' i ' , ' o ' , ' p ' , ' [ ' , ' ] ' , 0 , 0 , ' a ' , ' s ' ,
' d ' , ' f ' , ' g ' , ' h ' , ' j ' , ' k ' , ' l ' , ' ; ' , 39 , ' ` ' , 0 , 92 , ' z ' , ' x ' , ' c ' , ' v ' ,
' b ' , ' n ' , ' m ' , ' , ' , ' . ' , ' / ' , 0 , ' * ' , 0 , 32 , 0 , 0 , 0 , 0 , 0 , 0 ,
0 , 0 , 0 , 0 , 0 , 0 , 0 , ' 7 ' , ' 8 ' , ' 9 ' , ' - ' , ' 4 ' , ' 5 ' , ' 6 ' , ' + ' , ' 1 ' ,
' 2 ' , ' 3 ' , ' 0 ' , ' . ' , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
} ;
2011-03-04 07:04:42 +00:00
int32_t defaultres [ ] [ 2 ] =
{
2011-03-04 10:09:12 +00:00
{ 1920 , 1440 } , { 1920 , 1200 } , { 1920 , 1080 } , { 1600 , 1200 } , { 1600 , 900 } , { 1366 , 768 } , { 1280 , 1024 } ,
{ 1280 , 960 } , { 1152 , 864 } , { 1024 , 768 } , { 1024 , 600 } , { 800 , 600 } , { 640 , 480 } , { 640 , 400 } ,
{ 512 , 384 } , { 480 , 360 } , { 400 , 300 } , { 320 , 240 } , { 320 , 200 } , { 0 , 0 }
2011-03-04 07:04:42 +00:00
} ;
2010-05-25 10:56:00 +00:00
void SetKey ( int32_t key , int32_t state )
{
keystatus [ remap [ key ] ] = state ;
2011-01-16 02:50:27 +00:00
if ( state )
2010-05-25 10:56:00 +00:00
{
keyfifo [ keyfifoend ] = remap [ key ] ;
keyfifo [ ( keyfifoend + 1 ) & ( KEYFIFOSIZ - 1 ) ] = state ;
keyfifoend = ( ( keyfifoend + 2 ) & ( KEYFIFOSIZ - 1 ) ) ;
}
}
//
// bgetchar, bflushchars -- character-based input functions
//
char bgetchar ( void )
{
if ( keyasciififoplc = = keyasciififoend )
return 0 ;
{
char c = keyasciififo [ keyasciififoplc ] ;
keyasciififoplc = ( ( keyasciififoplc + 1 ) & ( KEYFIFOSIZ - 1 ) ) ;
return c ;
}
}
void bflushchars ( void )
{
Bmemset ( & keyasciififo , 0 , sizeof ( keyasciififo ) ) ;
keyasciififoplc = keyasciififoend = 0 ;
}
const char * getkeyname ( int32_t num )
{
return ( ( unsigned ) num > = 256 ) ? NULL : key_names [ num ] ;
}
2011-04-07 01:16:29 +00:00
void readmousexy ( int32_t * x , int32_t * y )
{
if ( ! moustat | | ! mousegrab | | ! appactive ) { * x = * y = 0 ; return ; }
* x = mousex ;
* y = mousey ;
mousex = mousey = 0 ;
}
void readmousebstatus ( int32_t * b )
{
if ( ! moustat | | ! mousegrab | | ! appactive ) { * b = 0 ; return ; }
* b = mouseb ;
}
2006-04-23 06:44:19 +00:00
# ifdef USE_OPENGL
2010-05-02 23:27:30 +00:00
struct glinfo_t glinfo =
2007-12-12 17:42:14 +00:00
{
2009-09-30 01:26:13 +00:00
" Unknown " , // vendor
" Unknown " , // renderer
" 0.0.0 " , // version
" " , // extensions
1.0 , // max anisotropy
0 , // brga texture format
0 , // clamp-to-edge support
0 , // texture compression
0 , // non-power-of-two textures
0 , // multisampling
0 , // nvidia multisampling hint
0 , // ARBfp
0 , // depth textures
0 , // shadow comparison
0 , // Frame Buffer Objects
0 , // rectangle textures
0 , // multitexturing
0 , // env_combine
0 , // Vertex Buffer Objects
0 , // VSync support
0 , // Shader Model 4 support
0 , // Occlusion Queries
0 , // GLSL
2011-10-02 05:56:35 +00:00
0 , // Debug Output
2009-09-30 01:26:13 +00:00
0 , // GL info dumped
2007-12-12 17:42:14 +00:00
} ;
2006-04-23 06:44:19 +00:00
# endif
2010-05-16 22:53:08 +00:00
char * Bstrtolower ( char * str )
2008-12-31 09:07:49 +00:00
{
2010-05-16 22:53:08 +00:00
if ( ! str ) return NULL ;
2008-12-31 09:07:49 +00:00
{
2010-05-16 22:53:08 +00:00
int32_t i = 0 , len = Bstrlen ( str ) ;
if ( len < = 0 ) return str ;
do
{
* ( str + i ) = Btolower ( * ( str + i ) ) ;
i + + ;
}
while ( - - len ) ;
2008-12-31 09:07:49 +00:00
}
2010-05-16 22:53:08 +00:00
2008-12-31 09:07:49 +00:00
return str ;
}
2009-06-13 21:06:45 +00:00
int32_t flushlogwindow = 1 ;
2009-01-06 06:59:18 +00:00
2009-01-09 09:29:17 +00:00
static void onvideomodechange ( int32_t newmode ) { UNREFERENCED_PARAMETER ( newmode ) ; }
void ( * baselayer_onvideomodechange ) ( int32_t ) = onvideomodechange ;
2006-04-23 06:44:19 +00:00
2011-03-04 08:50:58 +00:00
# ifdef USE_OPENGL
2009-01-09 09:29:17 +00:00
static int32_t osdfunc_setrendermode ( const osdfuncparm_t * parm )
2006-04-23 06:44:19 +00:00
{
2009-01-09 09:29:17 +00:00
int32_t m ;
2006-04-24 19:04:22 +00:00
char * p ;
2006-04-23 06:44:19 +00:00
2011-02-21 23:08:21 +00:00
const char * modestrs [ ] =
2007-12-12 17:42:14 +00:00
{
2010-05-25 10:56:00 +00:00
" classic software " , " " ,
" " , " polygonal OpenGL " , " great justice (Polymer) "
2007-12-12 17:42:14 +00:00
} ;
2006-04-23 06:44:19 +00:00
2006-04-24 19:04:22 +00:00
if ( parm - > numparms ! = 1 ) return OSDCMD_SHOWHELP ;
m = Bstrtol ( parm - > parms [ 0 ] , & p , 10 ) ;
2006-04-23 06:44:19 +00:00
2006-08-29 01:58:59 +00:00
if ( m < 0 | | m > 4 ) return OSDCMD_SHOWHELP ;
2006-04-23 06:44:19 +00:00
2006-04-24 19:04:22 +00:00
setrendermode ( m ) ;
2007-12-12 17:42:14 +00:00
OSD_Printf ( " Rendering method changed to %s \n " , modestrs [ getrendermode ( ) ] ) ;
2006-04-23 06:44:19 +00:00
2006-04-24 19:04:22 +00:00
return OSDCMD_OK ;
2006-04-23 06:44:19 +00:00
}
2008-07-12 23:44:07 +00:00
# if defined(USE_OPENGL)
2006-04-23 06:44:19 +00:00
# ifdef DEBUGGINGAIDS
2009-01-09 09:29:17 +00:00
static int32_t osdcmd_hicsetpalettetint ( const osdfuncparm_t * parm )
2006-04-23 06:44:19 +00:00
{
2009-01-09 09:29:17 +00:00
int32_t pal , cols [ 3 ] , eff ;
2006-04-24 19:04:22 +00:00
if ( parm - > numparms ! = 5 ) return OSDCMD_SHOWHELP ;
pal = Batol ( parm - > parms [ 0 ] ) ;
cols [ 0 ] = Batol ( parm - > parms [ 1 ] ) ;
cols [ 1 ] = Batol ( parm - > parms [ 2 ] ) ;
cols [ 2 ] = Batol ( parm - > parms [ 3 ] ) ;
eff = Batol ( parm - > parms [ 4 ] ) ;
hicsetpalettetint ( pal , cols [ 0 ] , cols [ 1 ] , cols [ 2 ] , eff ) ;
return OSDCMD_OK ;
2006-04-23 06:44:19 +00:00
}
# endif
2009-01-09 09:29:17 +00:00
int32_t osdcmd_glinfo ( const osdfuncparm_t * parm )
2006-04-23 06:44:19 +00:00
{
2006-04-24 19:04:22 +00:00
char * s , * t , * u , i ;
2008-03-22 10:23:57 +00:00
UNREFERENCED_PARAMETER ( parm ) ;
2007-12-12 17:42:14 +00:00
if ( bpp = = 8 )
{
2008-02-24 00:46:57 +00:00
initprintf ( " glinfo: Not in OpenGL mode. \n " ) ;
2006-04-24 19:04:22 +00:00
return OSDCMD_OK ;
}
2008-02-24 00:46:57 +00:00
initprintf ( " OpenGL Information: \n "
2006-04-24 19:04:22 +00:00
" Version: %s \n "
" Vendor: %s \n "
2008-07-09 23:25:38 +00:00
" Renderer: %s \n " ,
glinfo . version ,
glinfo . vendor ,
glinfo . renderer ) ;
if ( ! glinfo . dumped )
return OSDCMD_OK ;
initprintf ( " Maximum anisotropy: %.1f%s \n "
2006-04-24 19:04:22 +00:00
" BGRA textures: %s \n "
2009-09-30 01:26:13 +00:00
" Non-power-of-2 textures: %s \n "
2006-04-24 19:04:22 +00:00
" Texure compression: %s \n "
" Clamp-to-edge: %s \n "
" Multisampling: %s \n "
" Nvidia multisample hint: %s \n "
2007-01-06 01:29:45 +00:00
" ARBfp fragment programs: %s \n "
" Depth textures: %s \n "
" Shadow textures: %s \n "
" Frame Buffer Objects: %s \n "
" Rectangle textures: %s \n "
2007-03-08 03:07:10 +00:00
" Multitexturing: %s \n "
" env_combine: %s \n "
" Vertex Buffer Objects: %s \n "
2009-02-05 08:56:59 +00:00
" Shader Model 4: %s \n "
2009-09-30 01:26:13 +00:00
" Occlusion queries: %s \n "
" GLSL: %s \n "
2011-10-02 05:56:35 +00:00
" Debug Output: %s \n "
2006-04-24 19:04:22 +00:00
" Extensions: \n " ,
glinfo . maxanisotropy , glinfo . maxanisotropy > 1.0 ? " " : " (no anisotropic filtering) " ,
glinfo . bgra ? " supported " : " not supported " ,
glinfo . texnpot ? " supported " : " not supported " ,
glinfo . texcompr ? " supported " : " not supported " ,
glinfo . clamptoedge ? " supported " : " not supported " ,
glinfo . multisample ? " supported " : " not supported " ,
2007-01-06 01:29:45 +00:00
glinfo . nvmultisamplehint ? " supported " : " not supported " ,
glinfo . arbfp ? " supported " : " not supported " ,
glinfo . depthtex ? " supported " : " not supported " ,
glinfo . shadow ? " supported " : " not supported " ,
glinfo . fbos ? " supported " : " not supported " ,
2007-03-08 03:07:10 +00:00
glinfo . rect ? " supported " : " not supported " ,
glinfo . multitex ? " supported " : " not supported " ,
glinfo . envcombine ? " supported " : " not supported " ,
2009-02-05 08:56:59 +00:00
glinfo . vbos ? " supported " : " not supported " ,
2009-09-30 01:26:13 +00:00
glinfo . sm4 ? " supported " : " not supported " ,
glinfo . occlusionqueries ? " supported " : " not supported " ,
2011-10-02 05:56:35 +00:00
glinfo . glsl ? " supported " : " not supported " ,
glinfo . debugoutput ? " supported " : " not supported "
2006-04-24 19:04:22 +00:00
) ;
s = Bstrdup ( glinfo . extensions ) ;
2010-12-19 22:47:10 +00:00
if ( ! s ) initprintf ( " %s " , glinfo . extensions ) ;
2007-12-12 17:42:14 +00:00
else
{
2006-04-24 19:04:22 +00:00
i = 0 ; t = u = s ;
2007-12-12 17:42:14 +00:00
while ( * t )
{
if ( * t = = ' ' )
{
if ( i & 1 )
{
2006-04-24 19:04:22 +00:00
* t = 0 ;
2008-02-24 00:46:57 +00:00
initprintf ( " %s \n " , u ) ;
2006-04-24 19:04:22 +00:00
u = t + 1 ;
}
i + + ;
}
t + + ;
}
2008-02-24 00:46:57 +00:00
if ( i & 1 ) initprintf ( " %s \n " , u ) ;
2006-04-24 19:04:22 +00:00
Bfree ( s ) ;
}
return OSDCMD_OK ;
2006-04-23 06:44:19 +00:00
}
# endif
2008-07-12 23:44:07 +00:00
# endif
2006-04-23 06:44:19 +00:00
2010-07-03 08:53:57 +00:00
static int32_t osdcmd_cvar_set_baselayer ( const osdfuncparm_t * parm )
2006-04-23 06:44:19 +00:00
{
2010-07-03 08:53:57 +00:00
int32_t r = osdcmd_cvar_set ( parm ) ;
2006-04-24 19:04:22 +00:00
2010-07-03 08:53:57 +00:00
if ( r ! = OSDCMD_OK ) return r ;
2011-01-16 02:50:27 +00:00
/*
if ( ! Bstrcasecmp ( parm - > name , " r_scrcaptureformat " ) )
2010-07-03 08:53:57 +00:00
{
2011-01-16 02:50:27 +00:00
const char * fmts [ ] = { " TGA " , " PCX " } ;
if ( showval ) { OSD_Printf ( " r_scrcaptureformat is %s \n " , fmts [ captureformat ] ) ; }
else
{
int32_t j ;
for ( j = 0 ; j < 2 ; j + + )
if ( ! Bstrcasecmp ( parm - > parms [ 0 ] , fmts [ j ] ) ) break ;
if ( j = = 2 ) return OSDCMD_SHOWHELP ;
captureformat = j ;
}
return OSDCMD_OK ;
2010-07-03 08:53:57 +00:00
}
2011-01-16 02:50:27 +00:00
else */
2010-07-03 08:53:57 +00:00
if ( ! Bstrcasecmp ( parm - > name , " vid_gamma " ) | | ! Bstrcasecmp ( parm - > name , " vid_brightness " ) | | ! Bstrcasecmp ( parm - > name , " vid_contrast " ) )
{
2011-01-27 06:35:52 +00:00
setbrightness ( GAMMA_CALC , 0 , 0 ) ;
2010-07-03 08:53:57 +00:00
return r ;
2006-04-24 19:04:22 +00:00
}
2010-07-03 08:53:57 +00:00
return r ;
2006-04-23 06:44:19 +00:00
}
2009-01-09 09:29:17 +00:00
int32_t baselayer_init ( void )
2006-04-23 06:44:19 +00:00
{
2009-04-29 06:20:07 +00:00
uint32_t i ;
cvar_t cvars_engine [ ] =
{
2011-01-16 02:50:27 +00:00
{ " r_usenewaspect " , " r_usenewaspect: enable/disable new screen aspect ratio determination code " , ( void * ) & r_usenewaspect , CVAR_BOOL , 0 , 1 } ,
{ " r_screenaspect " , " r_screenaspect: if using the new aspect code and in fullscreen, screen aspect ratio in the form XXYY, e.g. 1609 for 16:9 " , ( void * ) & r_screenxy , CVAR_UINT , 100 , 9999 } ,
{ " r_novoxmips " , " r_novoxmips: turn off/on the use of mipmaps when rendering 8-bit voxels " , ( void * ) & novoxmips , CVAR_BOOL , 0 , 1 } ,
{ " r_voxels " , " r_voxels: enable/disable automatic sprite->voxel rendering " , ( void * ) & usevoxels , CVAR_BOOL , 0 , 1 } ,
/* { "r_scrcaptureformat","r_scrcaptureformat: sets the output format for screenshots (TGA or PCX)",osdcmd_vars, CVAR_FUNCPTR, 0, 0 },*/
Support for drawing 'island sectors' for TROR/classic (and with limited
functionality, Polymost).
The new feature can be enabled/disabled with the 'r_tror_nomaskpass' cvar.
The basic idea is that when drawing lower or upper levels, a first pass
is performed that ignores all red walls for which the TROR nextwall link
'towards' the viewer arrives at a red wall. Thus, in the worst case, there
can be up to twice as many rendering passes now (when it is discovered that
the no-mask-pass isn't different that what would be drawn with the ordinary
one, the latter is skipped, since we've already drawn all needed geometry).
Hovever, this kind of multi-pass splitting is only suitable for simple scenes,
like the upper subway in the TROR test map. In particular, multiple islands
shouldn't 'see' each other.
Two issues are worth mentioning: first, care needs to be taken for translucent
ceilings or floors, since drawing them twice isn't the same as drawing them
once. This is done for classic, but not for Polymost. Second, sprites (which
are always drawn _after_ the geometry for a given pass) are still clipped to
the geometry of the ordinary pass, resulting in their disappearance from
certain angles.
--
Additionaly, a change made it into this commit that fixes redundant collection
of sprites in TROR:classic/Polymost.
git-svn-id: https://svn.eduke32.com/eduke32@2024 1a8010ca-5511-0410-912e-c29ae57300e0
2011-09-15 17:04:14 +00:00
# ifdef YAX_ENABLE
{ " r_tror_nomaskpass " , " r_tror_nomaskpass: enable/disable additional pass in TROR software rendering " , ( void * ) & r_tror_nomaskpass , CVAR_BOOL , 0 , 1 } ,
# endif
2011-01-16 02:50:27 +00:00
{ " vid_gamma " , " vid_gamma <gamma>: adjusts gamma ramp " , ( void * ) & vid_gamma , CVAR_DOUBLE | CVAR_FUNCPTR , 0 , 10 } ,
{ " vid_contrast " , " vid_contrast <gamma>: adjusts gamma ramp " , ( void * ) & vid_contrast , CVAR_DOUBLE | CVAR_FUNCPTR , 0 , 10 } ,
{ " vid_brightness " , " vid_brightness <gamma>: adjusts gamma ramp " , ( void * ) & vid_brightness , CVAR_DOUBLE | CVAR_FUNCPTR , 0 , 10 } ,
{ " debug1 " , " debug counter " , ( void * ) & debug1 , CVAR_FLOAT , - 100000 , 100000 } ,
{ " debug2 " , " debug counter " , ( void * ) & debug2 , CVAR_FLOAT , - 100000 , 100000 } ,
2009-04-29 06:20:07 +00:00
} ;
for ( i = 0 ; i < sizeof ( cvars_engine ) / sizeof ( cvars_engine [ 0 ] ) ; i + + )
{
2010-05-02 23:27:30 +00:00
if ( OSD_RegisterCvar ( & cvars_engine [ i ] ) )
continue ;
2011-04-07 01:16:29 +00:00
OSD_RegisterFunction ( cvars_engine [ i ] . name , cvars_engine [ i ] . desc ,
2011-01-16 02:50:27 +00:00
( cvars_engine [ i ] . type & CVAR_FUNCPTR ) ? osdcmd_cvar_set_baselayer : osdcmd_cvar_set ) ;
2009-04-29 06:20:07 +00:00
}
2011-03-04 08:50:58 +00:00
# ifdef USE_OPENGL
2006-04-24 19:04:22 +00:00
OSD_RegisterFunction ( " setrendermode " , " setrendermode <number>: sets the engine's rendering mode. \n "
" Mode numbers are: \n "
" 0 - Classic Build software \n "
2006-04-23 06:44:19 +00:00
# ifdef USE_OPENGL
2006-04-24 19:04:22 +00:00
" 3 - Polygonal OpenGL \n "
2010-05-25 10:56:00 +00:00
" 4 - Great justice renderer (Polymer) \n "
2006-04-23 06:44:19 +00:00
# endif
2006-04-24 19:04:22 +00:00
,
osdfunc_setrendermode ) ;
2009-05-07 16:00:49 +00:00
# ifdef USE_OPENGL
2009-12-13 01:23:44 +00:00
# ifdef DEBUGGINGAIDS
OSD_RegisterFunction ( " hicsetpalettetint " , " hicsetpalettetint: sets palette tinting values " , osdcmd_hicsetpalettetint ) ;
# endif
2006-04-24 19:04:22 +00:00
OSD_RegisterFunction ( " glinfo " , " glinfo: shows OpenGL information about the current OpenGL mode " , osdcmd_glinfo ) ;
2009-05-07 16:00:49 +00:00
# endif
2009-04-29 06:20:07 +00:00
polymost_initosdfuncs ( ) ;
2006-04-23 06:44:19 +00:00
# endif
2009-04-29 06:20:07 +00:00
2006-04-24 19:04:22 +00:00
return 0 ;
2006-04-23 06:44:19 +00:00
}
2011-06-19 18:30:32 +00:00
# if defined _WIN32
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
# elif defined __linux || defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ || defined __APPLE__
# include <sys / mman.h>
# endif
void makeasmwriteable ( void )
{
2011-06-20 21:07:47 +00:00
# ifndef NOASM
2011-06-19 18:30:32 +00:00
extern int32_t dep_begin , dep_end ;
# if defined _WIN32
DWORD oldprot ;
if ( ! VirtualProtect ( ( LPVOID ) & dep_begin , ( SIZE_T ) & dep_end - ( SIZE_T ) & dep_begin , PAGE_EXECUTE_READWRITE , & oldprot ) )
{
initprintf ( " Error making code writeable " ) ;
return ;
}
# elif defined __linux || defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ || defined __APPLE__
int32_t pagesize ;
size_t dep_begin_page ;
pagesize = sysconf ( _SC_PAGE_SIZE ) ;
if ( pagesize = = - 1 )
{
initprintf ( " Error getting system page size \n " ) ;
return ;
}
dep_begin_page = ( ( size_t ) & dep_begin ) & ~ ( pagesize - 1 ) ;
if ( mprotect ( ( void * ) dep_begin_page , ( size_t ) & dep_end - dep_begin_page , PROT_READ | PROT_WRITE ) < 0 )
{
initprintf ( " Error making code writeable (errno=%d) \n " , errno ) ;
return ;
}
# else
# error "Don't know how to unprotect the self-modifying assembly on this platform!"
# endif
# endif
}