Initial commit
This commit is contained in:
968
engine/platformX86UNIX/gl_types.h
Executable file
968
engine/platformX86UNIX/gl_types.h
Executable file
@ -0,0 +1,968 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
#ifndef _X86UNIX_GL_TYPES_H_
|
||||
#define _X86UNIX_GL_TYPES_H_
|
||||
|
||||
// added by JMQ:
|
||||
#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
|
||||
#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF
|
||||
|
||||
#define GL_FOG_COORDINATE_SOURCE_EXT 0x8450
|
||||
#define GL_FOG_COORDINATE_EXT 0x8451
|
||||
#define GL_FRAGMENT_DEPTH_EXT 0x8452
|
||||
#define GL_CURRENT_FOG_COORDINATE_EXT 0x8453
|
||||
#define GL_FOG_COORDINATE_ARRAY_TYPE_EXT 0x8454
|
||||
#define GL_FOG_COORDINATE_ARRAY_STRIDE_EXT 0x8455
|
||||
#define GL_FOG_COORDINATE_ARRAY_POINTER_EXT 0x8456
|
||||
#define GL_FOG_COORDINATE_ARRAY_EXT 0x8457
|
||||
|
||||
#define GL_COMPRESSED_ALPHA_ARB 0x84E9
|
||||
#define GL_COMPRESSED_LUMINANCE_ARB 0x84EA
|
||||
#define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB
|
||||
#define GL_COMPRESSED_INTENSITY_ARB 0x84EC
|
||||
#define GL_COMPRESSED_RGB_ARB 0x84ED
|
||||
#define GL_COMPRESSED_RGBA_ARB 0x84EE
|
||||
#define GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF
|
||||
#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB 0x86A0
|
||||
#define GL_TEXTURE_COMPRESSED_ARB 0x86A1
|
||||
#define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2
|
||||
#define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3
|
||||
|
||||
#ifndef GL_EXT_packed_pixels
|
||||
#define GL_UNSIGNED_BYTE_3_3_2_EXT 0x8032
|
||||
#define GL_UNSIGNED_SHORT_4_4_4_4_EXT 0x8033
|
||||
#define GL_UNSIGNED_SHORT_5_5_5_1_EXT 0x8034
|
||||
#define GL_UNSIGNED_INT_8_8_8_8_EXT 0x8035
|
||||
#define GL_UNSIGNED_INT_10_10_10_2_EXT 0x8036
|
||||
#endif
|
||||
|
||||
#ifndef GL_EXT_paletted_texture
|
||||
#define GL_COLOR_INDEX1_EXT 0x80E2
|
||||
#define GL_COLOR_INDEX2_EXT 0x80E3
|
||||
#define GL_COLOR_INDEX4_EXT 0x80E4
|
||||
#define GL_COLOR_INDEX8_EXT 0x80E5
|
||||
#define GL_COLOR_INDEX12_EXT 0x80E6
|
||||
#define GL_COLOR_INDEX16_EXT 0x80E7
|
||||
#define GL_TEXTURE_INDEX_SIZE_EXT 0x80ED
|
||||
#endif
|
||||
|
||||
#define GL_CLAMP_TO_EDGE_EXT 0x812F
|
||||
|
||||
#define GL_V12MTVFMT_EXT 0x8702
|
||||
#define GL_V12MTNVFMT_EXT 0x8703
|
||||
#define GL_V12FTVFMT_EXT 0x8704
|
||||
#define GL_V12FMTVFMT_EXT 0x8705
|
||||
|
||||
#ifndef GL_EXT_texture_env_combine
|
||||
#define GL_COMBINE_EXT 0x8570
|
||||
#define GL_COMBINE_RGB_EXT 0x8571
|
||||
#define GL_COMBINE_ALPHA_EXT 0x8572
|
||||
#define GL_RGB_SCALE_EXT 0x8573
|
||||
#define GL_ADD_SIGNED_EXT 0x8574
|
||||
#define GL_INTERPOLATE_EXT 0x8575
|
||||
#define GL_CONSTANT_EXT 0x8576
|
||||
#define GL_PRIMARY_COLOR_EXT 0x8577
|
||||
#define GL_PREVIOUS_EXT 0x8578
|
||||
#define GL_SOURCE0_RGB_EXT 0x8580
|
||||
#define GL_SOURCE1_RGB_EXT 0x8581
|
||||
#define GL_SOURCE2_RGB_EXT 0x8582
|
||||
#define GL_SOURCE3_RGB_EXT 0x8583
|
||||
#define GL_SOURCE4_RGB_EXT 0x8584
|
||||
#define GL_SOURCE5_RGB_EXT 0x8585
|
||||
#define GL_SOURCE6_RGB_EXT 0x8586
|
||||
#define GL_SOURCE7_RGB_EXT 0x8587
|
||||
#define GL_SOURCE0_ALPHA_EXT 0x8588
|
||||
#define GL_SOURCE1_ALPHA_EXT 0x8589
|
||||
#define GL_SOURCE2_ALPHA_EXT 0x858A
|
||||
#define GL_SOURCE3_ALPHA_EXT 0x858B
|
||||
#define GL_SOURCE4_ALPHA_EXT 0x858C
|
||||
#define GL_SOURCE5_ALPHA_EXT 0x858D
|
||||
#define GL_SOURCE6_ALPHA_EXT 0x858E
|
||||
#define GL_SOURCE7_ALPHA_EXT 0x858F
|
||||
#define GL_OPERAND0_RGB_EXT 0x8590
|
||||
#define GL_OPERAND1_RGB_EXT 0x8591
|
||||
#define GL_OPERAND2_RGB_EXT 0x8592
|
||||
#define GL_OPERAND3_RGB_EXT 0x8593
|
||||
#define GL_OPERAND4_RGB_EXT 0x8594
|
||||
#define GL_OPERAND5_RGB_EXT 0x8595
|
||||
#define GL_OPERAND6_RGB_EXT 0x8596
|
||||
#define GL_OPERAND7_RGB_EXT 0x8597
|
||||
#define GL_OPERAND0_ALPHA_EXT 0x8598
|
||||
#define GL_OPERAND1_ALPHA_EXT 0x8599
|
||||
#define GL_OPERAND2_ALPHA_EXT 0x859A
|
||||
#define GL_OPERAND3_ALPHA_EXT 0x859B
|
||||
#define GL_OPERAND4_ALPHA_EXT 0x859C
|
||||
#define GL_OPERAND5_ALPHA_EXT 0x859D
|
||||
#define GL_OPERAND6_ALPHA_EXT 0x859E
|
||||
#define GL_OPERAND7_ALPHA_EXT 0x859F
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 3.4
|
||||
*
|
||||
* Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#define GL_VERSION_1_1 1
|
||||
#define GL_VERSION_1_2 1
|
||||
|
||||
/*
|
||||
*
|
||||
* Datatypes
|
||||
*
|
||||
*/
|
||||
#ifdef CENTERLINE_CLPP
|
||||
#define signed
|
||||
#endif
|
||||
typedef unsigned int GLenum;
|
||||
typedef unsigned char GLboolean;
|
||||
typedef unsigned int GLbitfield;
|
||||
typedef void GLvoid;
|
||||
typedef signed char GLbyte; /* 1-byte signed */
|
||||
typedef short GLshort; /* 2-byte signed */
|
||||
typedef int GLint; /* 4-byte signed */
|
||||
typedef unsigned char GLubyte; /* 1-byte unsigned */
|
||||
typedef unsigned short GLushort; /* 2-byte unsigned */
|
||||
typedef unsigned int GLuint; /* 4-byte unsigned */
|
||||
typedef int GLsizei; /* 4-byte signed */
|
||||
typedef float GLfloat; /* single precision float */
|
||||
typedef float GLclampf; /* single precision float in [0,1] */
|
||||
typedef double GLdouble; /* double precision float */
|
||||
typedef double GLclampd; /* double precision float in [0,1] */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* Constants
|
||||
*
|
||||
*/
|
||||
|
||||
/* Boolean values */
|
||||
#define GL_FALSE 0x0
|
||||
#define GL_TRUE 0x1
|
||||
|
||||
/* Data types */
|
||||
#define GL_BYTE 0x1400
|
||||
#define GL_UNSIGNED_BYTE 0x1401
|
||||
#define GL_SHORT 0x1402
|
||||
#define GL_UNSIGNED_SHORT 0x1403
|
||||
#define GL_INT 0x1404
|
||||
#define GL_UNSIGNED_INT 0x1405
|
||||
#define GL_FLOAT 0x1406
|
||||
#define GL_DOUBLE 0x140A
|
||||
#define GL_2_BYTES 0x1407
|
||||
#define GL_3_BYTES 0x1408
|
||||
#define GL_4_BYTES 0x1409
|
||||
|
||||
/* Primitives */
|
||||
#define GL_POINTS 0x0000
|
||||
#define GL_LINES 0x0001
|
||||
#define GL_LINE_LOOP 0x0002
|
||||
#define GL_LINE_STRIP 0x0003
|
||||
#define GL_TRIANGLES 0x0004
|
||||
#define GL_TRIANGLE_STRIP 0x0005
|
||||
#define GL_TRIANGLE_FAN 0x0006
|
||||
#define GL_QUADS 0x0007
|
||||
#define GL_QUAD_STRIP 0x0008
|
||||
#define GL_POLYGON 0x0009
|
||||
|
||||
/* Vertex Arrays */
|
||||
#define GL_VERTEX_ARRAY 0x8074
|
||||
#define GL_NORMAL_ARRAY 0x8075
|
||||
#define GL_COLOR_ARRAY 0x8076
|
||||
#define GL_INDEX_ARRAY 0x8077
|
||||
#define GL_TEXTURE_COORD_ARRAY 0x8078
|
||||
#define GL_EDGE_FLAG_ARRAY 0x8079
|
||||
#define GL_VERTEX_ARRAY_SIZE 0x807A
|
||||
#define GL_VERTEX_ARRAY_TYPE 0x807B
|
||||
#define GL_VERTEX_ARRAY_STRIDE 0x807C
|
||||
#define GL_NORMAL_ARRAY_TYPE 0x807E
|
||||
#define GL_NORMAL_ARRAY_STRIDE 0x807F
|
||||
#define GL_COLOR_ARRAY_SIZE 0x8081
|
||||
#define GL_COLOR_ARRAY_TYPE 0x8082
|
||||
#define GL_COLOR_ARRAY_STRIDE 0x8083
|
||||
#define GL_INDEX_ARRAY_TYPE 0x8085
|
||||
#define GL_INDEX_ARRAY_STRIDE 0x8086
|
||||
#define GL_TEXTURE_COORD_ARRAY_SIZE 0x8088
|
||||
#define GL_TEXTURE_COORD_ARRAY_TYPE 0x8089
|
||||
#define GL_TEXTURE_COORD_ARRAY_STRIDE 0x808A
|
||||
#define GL_EDGE_FLAG_ARRAY_STRIDE 0x808C
|
||||
#define GL_VERTEX_ARRAY_POINTER 0x808E
|
||||
#define GL_NORMAL_ARRAY_POINTER 0x808F
|
||||
#define GL_COLOR_ARRAY_POINTER 0x8090
|
||||
#define GL_INDEX_ARRAY_POINTER 0x8091
|
||||
#define GL_TEXTURE_COORD_ARRAY_POINTER 0x8092
|
||||
#define GL_EDGE_FLAG_ARRAY_POINTER 0x8093
|
||||
#define GL_V2F 0x2A20
|
||||
#define GL_V3F 0x2A21
|
||||
#define GL_C4UB_V2F 0x2A22
|
||||
#define GL_C4UB_V3F 0x2A23
|
||||
#define GL_C3F_V3F 0x2A24
|
||||
#define GL_N3F_V3F 0x2A25
|
||||
#define GL_C4F_N3F_V3F 0x2A26
|
||||
#define GL_T2F_V3F 0x2A27
|
||||
#define GL_T4F_V4F 0x2A28
|
||||
#define GL_T2F_C4UB_V3F 0x2A29
|
||||
#define GL_T2F_C3F_V3F 0x2A2A
|
||||
#define GL_T2F_N3F_V3F 0x2A2B
|
||||
#define GL_T2F_C4F_N3F_V3F 0x2A2C
|
||||
#define GL_T4F_C4F_N3F_V4F 0x2A2D
|
||||
|
||||
/* Matrix Mode */
|
||||
#define GL_MATRIX_MODE 0x0BA0
|
||||
#define GL_MODELVIEW 0x1700
|
||||
#define GL_PROJECTION 0x1701
|
||||
#define GL_TEXTURE 0x1702
|
||||
|
||||
/* Points */
|
||||
#define GL_POINT_SMOOTH 0x0B10
|
||||
#define GL_POINT_SIZE 0x0B11
|
||||
#define GL_POINT_SIZE_GRANULARITY 0x0B13
|
||||
#define GL_POINT_SIZE_RANGE 0x0B12
|
||||
|
||||
/* Lines */
|
||||
#define GL_LINE_SMOOTH 0x0B20
|
||||
#define GL_LINE_STIPPLE 0x0B24
|
||||
#define GL_LINE_STIPPLE_PATTERN 0x0B25
|
||||
#define GL_LINE_STIPPLE_REPEAT 0x0B26
|
||||
#define GL_LINE_WIDTH 0x0B21
|
||||
#define GL_LINE_WIDTH_GRANULARITY 0x0B23
|
||||
#define GL_LINE_WIDTH_RANGE 0x0B22
|
||||
|
||||
/* Polygons */
|
||||
#define GL_POINT 0x1B00
|
||||
#define GL_LINE 0x1B01
|
||||
#define GL_FILL 0x1B02
|
||||
#define GL_CW 0x0900
|
||||
#define GL_CCW 0x0901
|
||||
#define GL_FRONT 0x0404
|
||||
#define GL_BACK 0x0405
|
||||
#define GL_POLYGON_MODE 0x0B40
|
||||
#define GL_POLYGON_SMOOTH 0x0B41
|
||||
#define GL_POLYGON_STIPPLE 0x0B42
|
||||
#define GL_EDGE_FLAG 0x0B43
|
||||
#define GL_CULL_FACE 0x0B44
|
||||
#define GL_CULL_FACE_MODE 0x0B45
|
||||
#define GL_FRONT_FACE 0x0B46
|
||||
#define GL_POLYGON_OFFSET_FACTOR 0x8038
|
||||
#define GL_POLYGON_OFFSET_UNITS 0x2A00
|
||||
#define GL_POLYGON_OFFSET_POINT 0x2A01
|
||||
#define GL_POLYGON_OFFSET_LINE 0x2A02
|
||||
#define GL_POLYGON_OFFSET_FILL 0x8037
|
||||
|
||||
/* Display Lists */
|
||||
#define GL_COMPILE 0x1300
|
||||
#define GL_COMPILE_AND_EXECUTE 0x1301
|
||||
#define GL_LIST_BASE 0x0B32
|
||||
#define GL_LIST_INDEX 0x0B33
|
||||
#define GL_LIST_MODE 0x0B30
|
||||
|
||||
/* Depth buffer */
|
||||
#define GL_NEVER 0x0200
|
||||
#define GL_LESS 0x0201
|
||||
#define GL_EQUAL 0x0202
|
||||
#define GL_LEQUAL 0x0203
|
||||
#define GL_GREATER 0x0204
|
||||
#define GL_NOTEQUAL 0x0205
|
||||
#define GL_GEQUAL 0x0206
|
||||
#define GL_ALWAYS 0x0207
|
||||
#define GL_DEPTH_TEST 0x0B71
|
||||
#define GL_DEPTH_BITS 0x0D56
|
||||
#define GL_DEPTH_CLEAR_VALUE 0x0B73
|
||||
#define GL_DEPTH_FUNC 0x0B74
|
||||
#define GL_DEPTH_RANGE 0x0B70
|
||||
#define GL_DEPTH_WRITEMASK 0x0B72
|
||||
#define GL_DEPTH_COMPONENT 0x1902
|
||||
|
||||
/* Lighting */
|
||||
#define GL_LIGHTING 0x0B50
|
||||
#define GL_LIGHT0 0x4000
|
||||
#define GL_LIGHT1 0x4001
|
||||
#define GL_LIGHT2 0x4002
|
||||
#define GL_LIGHT3 0x4003
|
||||
#define GL_LIGHT4 0x4004
|
||||
#define GL_LIGHT5 0x4005
|
||||
#define GL_LIGHT6 0x4006
|
||||
#define GL_LIGHT7 0x4007
|
||||
#define GL_SPOT_EXPONENT 0x1205
|
||||
#define GL_SPOT_CUTOFF 0x1206
|
||||
#define GL_CONSTANT_ATTENUATION 0x1207
|
||||
#define GL_LINEAR_ATTENUATION 0x1208
|
||||
#define GL_QUADRATIC_ATTENUATION 0x1209
|
||||
#define GL_AMBIENT 0x1200
|
||||
#define GL_DIFFUSE 0x1201
|
||||
#define GL_SPECULAR 0x1202
|
||||
#define GL_SHININESS 0x1601
|
||||
#define GL_EMISSION 0x1600
|
||||
#define GL_POSITION 0x1203
|
||||
#define GL_SPOT_DIRECTION 0x1204
|
||||
#define GL_AMBIENT_AND_DIFFUSE 0x1602
|
||||
#define GL_COLOR_INDEXES 0x1603
|
||||
#define GL_LIGHT_MODEL_TWO_SIDE 0x0B52
|
||||
#define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51
|
||||
#define GL_LIGHT_MODEL_AMBIENT 0x0B53
|
||||
#define GL_FRONT_AND_BACK 0x0408
|
||||
#define GL_SHADE_MODEL 0x0B54
|
||||
#define GL_FLAT 0x1D00
|
||||
#define GL_SMOOTH 0x1D01
|
||||
#define GL_COLOR_MATERIAL 0x0B57
|
||||
#define GL_COLOR_MATERIAL_FACE 0x0B55
|
||||
#define GL_COLOR_MATERIAL_PARAMETER 0x0B56
|
||||
#define GL_NORMALIZE 0x0BA1
|
||||
|
||||
/* User clipping planes */
|
||||
#define GL_CLIP_PLANE0 0x3000
|
||||
#define GL_CLIP_PLANE1 0x3001
|
||||
#define GL_CLIP_PLANE2 0x3002
|
||||
#define GL_CLIP_PLANE3 0x3003
|
||||
#define GL_CLIP_PLANE4 0x3004
|
||||
#define GL_CLIP_PLANE5 0x3005
|
||||
|
||||
/* Accumulation buffer */
|
||||
#define GL_ACCUM_RED_BITS 0x0D58
|
||||
#define GL_ACCUM_GREEN_BITS 0x0D59
|
||||
#define GL_ACCUM_BLUE_BITS 0x0D5A
|
||||
#define GL_ACCUM_ALPHA_BITS 0x0D5B
|
||||
#define GL_ACCUM_CLEAR_VALUE 0x0B80
|
||||
#define GL_ACCUM 0x0100
|
||||
#define GL_ADD 0x0104
|
||||
#define GL_LOAD 0x0101
|
||||
#define GL_MULT 0x0103
|
||||
#define GL_RETURN 0x0102
|
||||
|
||||
/* Alpha testing */
|
||||
#define GL_ALPHA_TEST 0x0BC0
|
||||
#define GL_ALPHA_TEST_REF 0x0BC2
|
||||
#define GL_ALPHA_TEST_FUNC 0x0BC1
|
||||
|
||||
/* Blending */
|
||||
#define GL_BLEND 0x0BE2
|
||||
#define GL_BLEND_SRC 0x0BE1
|
||||
#define GL_BLEND_DST 0x0BE0
|
||||
#define GL_ZERO 0x0
|
||||
#define GL_ONE 0x1
|
||||
#define GL_SRC_COLOR 0x0300
|
||||
#define GL_ONE_MINUS_SRC_COLOR 0x0301
|
||||
#define GL_DST_COLOR 0x0306
|
||||
#define GL_ONE_MINUS_DST_COLOR 0x0307
|
||||
#define GL_SRC_ALPHA 0x0302
|
||||
#define GL_ONE_MINUS_SRC_ALPHA 0x0303
|
||||
#define GL_DST_ALPHA 0x0304
|
||||
#define GL_ONE_MINUS_DST_ALPHA 0x0305
|
||||
#define GL_SRC_ALPHA_SATURATE 0x0308
|
||||
#define GL_CONSTANT_COLOR 0x8001
|
||||
#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002
|
||||
#define GL_CONSTANT_ALPHA 0x8003
|
||||
#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004
|
||||
|
||||
/* Render Mode */
|
||||
#define GL_FEEDBACK 0x1C01
|
||||
#define GL_RENDER 0x1C00
|
||||
#define GL_SELECT 0x1C02
|
||||
|
||||
/* Feedback */
|
||||
#define GL_2D 0x0600
|
||||
#define GL_3D 0x0601
|
||||
#define GL_3D_COLOR 0x0602
|
||||
#define GL_3D_COLOR_TEXTURE 0x0603
|
||||
#define GL_4D_COLOR_TEXTURE 0x0604
|
||||
#define GL_POINT_TOKEN 0x0701
|
||||
#define GL_LINE_TOKEN 0x0702
|
||||
#define GL_LINE_RESET_TOKEN 0x0707
|
||||
#define GL_POLYGON_TOKEN 0x0703
|
||||
#define GL_BITMAP_TOKEN 0x0704
|
||||
#define GL_DRAW_PIXEL_TOKEN 0x0705
|
||||
#define GL_COPY_PIXEL_TOKEN 0x0706
|
||||
#define GL_PASS_THROUGH_TOKEN 0x0700
|
||||
#define GL_FEEDBACK_BUFFER_POINTER 0x0DF0
|
||||
#define GL_FEEDBACK_BUFFER_SIZE 0x0DF1
|
||||
#define GL_FEEDBACK_BUFFER_TYPE 0x0DF2
|
||||
|
||||
/* Selection */
|
||||
#define GL_SELECTION_BUFFER_POINTER 0x0DF3
|
||||
#define GL_SELECTION_BUFFER_SIZE 0x0DF4
|
||||
|
||||
/* Fog */
|
||||
#define GL_FOG 0x0B60
|
||||
#define GL_FOG_MODE 0x0B65
|
||||
#define GL_FOG_DENSITY 0x0B62
|
||||
#define GL_FOG_COLOR 0x0B66
|
||||
#define GL_FOG_INDEX 0x0B61
|
||||
#define GL_FOG_START 0x0B63
|
||||
#define GL_FOG_END 0x0B64
|
||||
#define GL_LINEAR 0x2601
|
||||
#define GL_EXP 0x0800
|
||||
#define GL_EXP2 0x0801
|
||||
|
||||
/* Logic Ops */
|
||||
#define GL_LOGIC_OP 0x0BF1
|
||||
#define GL_INDEX_LOGIC_OP 0x0BF1
|
||||
#define GL_COLOR_LOGIC_OP 0x0BF2
|
||||
#define GL_LOGIC_OP_MODE 0x0BF0
|
||||
#define GL_CLEAR 0x1500
|
||||
#define GL_SET 0x150F
|
||||
#define GL_COPY 0x1503
|
||||
#define GL_COPY_INVERTED 0x150C
|
||||
#define GL_NOOP 0x1505
|
||||
#define GL_INVERT 0x150A
|
||||
#define GL_AND 0x1501
|
||||
#define GL_NAND 0x150E
|
||||
#define GL_OR 0x1507
|
||||
#define GL_NOR 0x1508
|
||||
#define GL_XOR 0x1506
|
||||
#define GL_EQUIV 0x1509
|
||||
#define GL_AND_REVERSE 0x1502
|
||||
#define GL_AND_INVERTED 0x1504
|
||||
#define GL_OR_REVERSE 0x150B
|
||||
#define GL_OR_INVERTED 0x150D
|
||||
|
||||
/* Stencil */
|
||||
#define GL_STENCIL_TEST 0x0B90
|
||||
#define GL_STENCIL_WRITEMASK 0x0B98
|
||||
#define GL_STENCIL_BITS 0x0D57
|
||||
#define GL_STENCIL_FUNC 0x0B92
|
||||
#define GL_STENCIL_VALUE_MASK 0x0B93
|
||||
#define GL_STENCIL_REF 0x0B97
|
||||
#define GL_STENCIL_FAIL 0x0B94
|
||||
#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96
|
||||
#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95
|
||||
#define GL_STENCIL_CLEAR_VALUE 0x0B91
|
||||
#define GL_STENCIL_INDEX 0x1901
|
||||
#define GL_KEEP 0x1E00
|
||||
#define GL_REPLACE 0x1E01
|
||||
#define GL_INCR 0x1E02
|
||||
#define GL_DECR 0x1E03
|
||||
|
||||
/* Buffers, Pixel Drawing/Reading */
|
||||
#define GL_NONE 0x0
|
||||
#define GL_LEFT 0x0406
|
||||
#define GL_RIGHT 0x0407
|
||||
/*GL_FRONT 0x0404 */
|
||||
/*GL_BACK 0x0405 */
|
||||
/*GL_FRONT_AND_BACK 0x0408 */
|
||||
#define GL_FRONT_LEFT 0x0400
|
||||
#define GL_FRONT_RIGHT 0x0401
|
||||
#define GL_BACK_LEFT 0x0402
|
||||
#define GL_BACK_RIGHT 0x0403
|
||||
#define GL_AUX0 0x0409
|
||||
#define GL_AUX1 0x040A
|
||||
#define GL_AUX2 0x040B
|
||||
#define GL_AUX3 0x040C
|
||||
#define GL_COLOR_INDEX 0x1900
|
||||
#define GL_RED 0x1903
|
||||
#define GL_GREEN 0x1904
|
||||
#define GL_BLUE 0x1905
|
||||
#define GL_ALPHA 0x1906
|
||||
#define GL_LUMINANCE 0x1909
|
||||
#define GL_LUMINANCE_ALPHA 0x190A
|
||||
#define GL_ALPHA_BITS 0x0D55
|
||||
#define GL_RED_BITS 0x0D52
|
||||
#define GL_GREEN_BITS 0x0D53
|
||||
#define GL_BLUE_BITS 0x0D54
|
||||
#define GL_INDEX_BITS 0x0D51
|
||||
#define GL_SUBPIXEL_BITS 0x0D50
|
||||
#define GL_AUX_BUFFERS 0x0C00
|
||||
#define GL_READ_BUFFER 0x0C02
|
||||
#define GL_DRAW_BUFFER 0x0C01
|
||||
#define GL_DOUBLEBUFFER 0x0C32
|
||||
#define GL_STEREO 0x0C33
|
||||
#define GL_BITMAP 0x1A00
|
||||
#define GL_COLOR 0x1800
|
||||
#define GL_DEPTH 0x1801
|
||||
#define GL_STENCIL 0x1802
|
||||
#define GL_DITHER 0x0BD0
|
||||
#define GL_RGB 0x1907
|
||||
#define GL_RGBA 0x1908
|
||||
|
||||
/* Implementation limits */
|
||||
#define GL_MAX_LIST_NESTING 0x0B31
|
||||
#define GL_MAX_ATTRIB_STACK_DEPTH 0x0D35
|
||||
#define GL_MAX_MODELVIEW_STACK_DEPTH 0x0D36
|
||||
#define GL_MAX_NAME_STACK_DEPTH 0x0D37
|
||||
#define GL_MAX_PROJECTION_STACK_DEPTH 0x0D38
|
||||
#define GL_MAX_TEXTURE_STACK_DEPTH 0x0D39
|
||||
#define GL_MAX_EVAL_ORDER 0x0D30
|
||||
#define GL_MAX_LIGHTS 0x0D31
|
||||
#define GL_MAX_CLIP_PLANES 0x0D32
|
||||
#define GL_MAX_TEXTURE_SIZE 0x0D33
|
||||
#define GL_MAX_PIXEL_MAP_TABLE 0x0D34
|
||||
#define GL_MAX_VIEWPORT_DIMS 0x0D3A
|
||||
#define GL_MAX_CLIENT_ATTRIB_STACK_DEPTH 0x0D3B
|
||||
|
||||
/* Gets */
|
||||
#define GL_ATTRIB_STACK_DEPTH 0x0BB0
|
||||
#define GL_CLIENT_ATTRIB_STACK_DEPTH 0x0BB1
|
||||
#define GL_COLOR_CLEAR_VALUE 0x0C22
|
||||
#define GL_COLOR_WRITEMASK 0x0C23
|
||||
#define GL_CURRENT_INDEX 0x0B01
|
||||
#define GL_CURRENT_COLOR 0x0B00
|
||||
#define GL_CURRENT_NORMAL 0x0B02
|
||||
#define GL_CURRENT_RASTER_COLOR 0x0B04
|
||||
#define GL_CURRENT_RASTER_DISTANCE 0x0B09
|
||||
#define GL_CURRENT_RASTER_INDEX 0x0B05
|
||||
#define GL_CURRENT_RASTER_POSITION 0x0B07
|
||||
#define GL_CURRENT_RASTER_TEXTURE_COORDS 0x0B06
|
||||
#define GL_CURRENT_RASTER_POSITION_VALID 0x0B08
|
||||
#define GL_CURRENT_TEXTURE_COORDS 0x0B03
|
||||
#define GL_INDEX_CLEAR_VALUE 0x0C20
|
||||
#define GL_INDEX_MODE 0x0C30
|
||||
#define GL_INDEX_WRITEMASK 0x0C21
|
||||
#define GL_MODELVIEW_MATRIX 0x0BA6
|
||||
#define GL_MODELVIEW_STACK_DEPTH 0x0BA3
|
||||
#define GL_NAME_STACK_DEPTH 0x0D70
|
||||
#define GL_PROJECTION_MATRIX 0x0BA7
|
||||
#define GL_PROJECTION_STACK_DEPTH 0x0BA4
|
||||
#define GL_RENDER_MODE 0x0C40
|
||||
#define GL_RGBA_MODE 0x0C31
|
||||
#define GL_TEXTURE_MATRIX 0x0BA8
|
||||
#define GL_TEXTURE_STACK_DEPTH 0x0BA5
|
||||
#define GL_VIEWPORT 0x0BA2
|
||||
|
||||
/* Evaluators */
|
||||
#define GL_AUTO_NORMAL 0x0D80
|
||||
#define GL_MAP1_COLOR_4 0x0D90
|
||||
#define GL_MAP1_GRID_DOMAIN 0x0DD0
|
||||
#define GL_MAP1_GRID_SEGMENTS 0x0DD1
|
||||
#define GL_MAP1_INDEX 0x0D91
|
||||
#define GL_MAP1_NORMAL 0x0D92
|
||||
#define GL_MAP1_TEXTURE_COORD_1 0x0D93
|
||||
#define GL_MAP1_TEXTURE_COORD_2 0x0D94
|
||||
#define GL_MAP1_TEXTURE_COORD_3 0x0D95
|
||||
#define GL_MAP1_TEXTURE_COORD_4 0x0D96
|
||||
#define GL_MAP1_VERTEX_3 0x0D97
|
||||
#define GL_MAP1_VERTEX_4 0x0D98
|
||||
#define GL_MAP2_COLOR_4 0x0DB0
|
||||
#define GL_MAP2_GRID_DOMAIN 0x0DD2
|
||||
#define GL_MAP2_GRID_SEGMENTS 0x0DD3
|
||||
#define GL_MAP2_INDEX 0x0DB1
|
||||
#define GL_MAP2_NORMAL 0x0DB2
|
||||
#define GL_MAP2_TEXTURE_COORD_1 0x0DB3
|
||||
#define GL_MAP2_TEXTURE_COORD_2 0x0DB4
|
||||
#define GL_MAP2_TEXTURE_COORD_3 0x0DB5
|
||||
#define GL_MAP2_TEXTURE_COORD_4 0x0DB6
|
||||
#define GL_MAP2_VERTEX_3 0x0DB7
|
||||
#define GL_MAP2_VERTEX_4 0x0DB8
|
||||
#define GL_COEFF 0x0A00
|
||||
#define GL_DOMAIN 0x0A02
|
||||
#define GL_ORDER 0x0A01
|
||||
|
||||
/* Hints */
|
||||
#define GL_FOG_HINT 0x0C54
|
||||
#define GL_LINE_SMOOTH_HINT 0x0C52
|
||||
#define GL_PERSPECTIVE_CORRECTION_HINT 0x0C50
|
||||
#define GL_POINT_SMOOTH_HINT 0x0C51
|
||||
#define GL_POLYGON_SMOOTH_HINT 0x0C53
|
||||
#define GL_DONT_CARE 0x1100
|
||||
#define GL_FASTEST 0x1101
|
||||
#define GL_NICEST 0x1102
|
||||
|
||||
/* Scissor box */
|
||||
#define GL_SCISSOR_TEST 0x0C11
|
||||
#define GL_SCISSOR_BOX 0x0C10
|
||||
|
||||
/* Pixel Mode / Transfer */
|
||||
#define GL_MAP_COLOR 0x0D10
|
||||
#define GL_MAP_STENCIL 0x0D11
|
||||
#define GL_INDEX_SHIFT 0x0D12
|
||||
#define GL_INDEX_OFFSET 0x0D13
|
||||
#define GL_RED_SCALE 0x0D14
|
||||
#define GL_RED_BIAS 0x0D15
|
||||
#define GL_GREEN_SCALE 0x0D18
|
||||
#define GL_GREEN_BIAS 0x0D19
|
||||
#define GL_BLUE_SCALE 0x0D1A
|
||||
#define GL_BLUE_BIAS 0x0D1B
|
||||
#define GL_ALPHA_SCALE 0x0D1C
|
||||
#define GL_ALPHA_BIAS 0x0D1D
|
||||
#define GL_DEPTH_SCALE 0x0D1E
|
||||
#define GL_DEPTH_BIAS 0x0D1F
|
||||
#define GL_PIXEL_MAP_S_TO_S_SIZE 0x0CB1
|
||||
#define GL_PIXEL_MAP_I_TO_I_SIZE 0x0CB0
|
||||
#define GL_PIXEL_MAP_I_TO_R_SIZE 0x0CB2
|
||||
#define GL_PIXEL_MAP_I_TO_G_SIZE 0x0CB3
|
||||
#define GL_PIXEL_MAP_I_TO_B_SIZE 0x0CB4
|
||||
#define GL_PIXEL_MAP_I_TO_A_SIZE 0x0CB5
|
||||
#define GL_PIXEL_MAP_R_TO_R_SIZE 0x0CB6
|
||||
#define GL_PIXEL_MAP_G_TO_G_SIZE 0x0CB7
|
||||
#define GL_PIXEL_MAP_B_TO_B_SIZE 0x0CB8
|
||||
#define GL_PIXEL_MAP_A_TO_A_SIZE 0x0CB9
|
||||
#define GL_PIXEL_MAP_S_TO_S 0x0C71
|
||||
#define GL_PIXEL_MAP_I_TO_I 0x0C70
|
||||
#define GL_PIXEL_MAP_I_TO_R 0x0C72
|
||||
#define GL_PIXEL_MAP_I_TO_G 0x0C73
|
||||
#define GL_PIXEL_MAP_I_TO_B 0x0C74
|
||||
#define GL_PIXEL_MAP_I_TO_A 0x0C75
|
||||
#define GL_PIXEL_MAP_R_TO_R 0x0C76
|
||||
#define GL_PIXEL_MAP_G_TO_G 0x0C77
|
||||
#define GL_PIXEL_MAP_B_TO_B 0x0C78
|
||||
#define GL_PIXEL_MAP_A_TO_A 0x0C79
|
||||
#define GL_PACK_ALIGNMENT 0x0D05
|
||||
#define GL_PACK_LSB_FIRST 0x0D01
|
||||
#define GL_PACK_ROW_LENGTH 0x0D02
|
||||
#define GL_PACK_SKIP_PIXELS 0x0D04
|
||||
#define GL_PACK_SKIP_ROWS 0x0D03
|
||||
#define GL_PACK_SWAP_BYTES 0x0D00
|
||||
#define GL_UNPACK_ALIGNMENT 0x0CF5
|
||||
#define GL_UNPACK_LSB_FIRST 0x0CF1
|
||||
#define GL_UNPACK_ROW_LENGTH 0x0CF2
|
||||
#define GL_UNPACK_SKIP_PIXELS 0x0CF4
|
||||
#define GL_UNPACK_SKIP_ROWS 0x0CF3
|
||||
#define GL_UNPACK_SWAP_BYTES 0x0CF0
|
||||
#define GL_ZOOM_X 0x0D16
|
||||
#define GL_ZOOM_Y 0x0D17
|
||||
|
||||
/* Texture mapping */
|
||||
#define GL_TEXTURE_ENV 0x2300
|
||||
#define GL_TEXTURE_ENV_MODE 0x2200
|
||||
#define GL_TEXTURE_1D 0x0DE0
|
||||
#define GL_TEXTURE_2D 0x0DE1
|
||||
#define GL_TEXTURE_WRAP_S 0x2802
|
||||
#define GL_TEXTURE_WRAP_T 0x2803
|
||||
#define GL_TEXTURE_MAG_FILTER 0x2800
|
||||
#define GL_TEXTURE_MIN_FILTER 0x2801
|
||||
#define GL_TEXTURE_ENV_COLOR 0x2201
|
||||
#define GL_TEXTURE_GEN_S 0x0C60
|
||||
#define GL_TEXTURE_GEN_T 0x0C61
|
||||
#define GL_TEXTURE_GEN_MODE 0x2500
|
||||
#define GL_TEXTURE_BORDER_COLOR 0x1004
|
||||
#define GL_TEXTURE_WIDTH 0x1000
|
||||
#define GL_TEXTURE_HEIGHT 0x1001
|
||||
#define GL_TEXTURE_BORDER 0x1005
|
||||
#define GL_TEXTURE_COMPONENTS 0x1003
|
||||
#define GL_TEXTURE_RED_SIZE 0x805C
|
||||
#define GL_TEXTURE_GREEN_SIZE 0x805D
|
||||
#define GL_TEXTURE_BLUE_SIZE 0x805E
|
||||
#define GL_TEXTURE_ALPHA_SIZE 0x805F
|
||||
#define GL_TEXTURE_LUMINANCE_SIZE 0x8060
|
||||
#define GL_TEXTURE_INTENSITY_SIZE 0x8061
|
||||
#define GL_NEAREST_MIPMAP_NEAREST 0x2700
|
||||
#define GL_NEAREST_MIPMAP_LINEAR 0x2702
|
||||
#define GL_LINEAR_MIPMAP_NEAREST 0x2701
|
||||
#define GL_LINEAR_MIPMAP_LINEAR 0x2703
|
||||
#define GL_OBJECT_LINEAR 0x2401
|
||||
#define GL_OBJECT_PLANE 0x2501
|
||||
#define GL_EYE_LINEAR 0x2400
|
||||
#define GL_EYE_PLANE 0x2502
|
||||
#define GL_SPHERE_MAP 0x2402
|
||||
#define GL_DECAL 0x2101
|
||||
#define GL_MODULATE 0x2100
|
||||
#define GL_NEAREST 0x2600
|
||||
#define GL_REPEAT 0x2901
|
||||
#define GL_CLAMP 0x2900
|
||||
#define GL_S 0x2000
|
||||
#define GL_T 0x2001
|
||||
#define GL_R 0x2002
|
||||
#define GL_Q 0x2003
|
||||
#define GL_TEXTURE_GEN_R 0x0C62
|
||||
#define GL_TEXTURE_GEN_Q 0x0C63
|
||||
|
||||
/* GL 1.1 texturing */
|
||||
#define GL_PROXY_TEXTURE_1D 0x8063
|
||||
#define GL_PROXY_TEXTURE_2D 0x8064
|
||||
#define GL_TEXTURE_PRIORITY 0x8066
|
||||
#define GL_TEXTURE_RESIDENT 0x8067
|
||||
#define GL_TEXTURE_BINDING_1D 0x8068
|
||||
#define GL_TEXTURE_BINDING_2D 0x8069
|
||||
#define GL_TEXTURE_INTERNAL_FORMAT 0x1003
|
||||
|
||||
/* GL 1.2 texturing */
|
||||
#define GL_PACK_SKIP_IMAGES 0x806B
|
||||
#define GL_PACK_IMAGE_HEIGHT 0x806C
|
||||
#define GL_UNPACK_SKIP_IMAGES 0x806D
|
||||
#define GL_UNPACK_IMAGE_HEIGHT 0x806E
|
||||
#define GL_TEXTURE_3D 0x806F
|
||||
#define GL_PROXY_TEXTURE_3D 0x8070
|
||||
#define GL_TEXTURE_DEPTH 0x8071
|
||||
#define GL_TEXTURE_WRAP_R 0x8072
|
||||
#define GL_MAX_3D_TEXTURE_SIZE 0x8073
|
||||
#define GL_TEXTURE_BINDING_3D 0x806A
|
||||
|
||||
/* Internal texture formats (GL 1.1) */
|
||||
#define GL_ALPHA4 0x803B
|
||||
#define GL_ALPHA8 0x803C
|
||||
#define GL_ALPHA12 0x803D
|
||||
#define GL_ALPHA16 0x803E
|
||||
#define GL_LUMINANCE4 0x803F
|
||||
#define GL_LUMINANCE8 0x8040
|
||||
#define GL_LUMINANCE12 0x8041
|
||||
#define GL_LUMINANCE16 0x8042
|
||||
#define GL_LUMINANCE4_ALPHA4 0x8043
|
||||
#define GL_LUMINANCE6_ALPHA2 0x8044
|
||||
#define GL_LUMINANCE8_ALPHA8 0x8045
|
||||
#define GL_LUMINANCE12_ALPHA4 0x8046
|
||||
#define GL_LUMINANCE12_ALPHA12 0x8047
|
||||
#define GL_LUMINANCE16_ALPHA16 0x8048
|
||||
#define GL_INTENSITY 0x8049
|
||||
#define GL_INTENSITY4 0x804A
|
||||
#define GL_INTENSITY8 0x804B
|
||||
#define GL_INTENSITY12 0x804C
|
||||
#define GL_INTENSITY16 0x804D
|
||||
#define GL_R3_G3_B2 0x2A10
|
||||
#define GL_RGB4 0x804F
|
||||
#define GL_RGB5 0x8050
|
||||
#define GL_RGB8 0x8051
|
||||
#define GL_RGB10 0x8052
|
||||
#define GL_RGB12 0x8053
|
||||
#define GL_RGB16 0x8054
|
||||
#define GL_RGBA2 0x8055
|
||||
#define GL_RGBA4 0x8056
|
||||
#define GL_RGB5_A1 0x8057
|
||||
#define GL_RGBA8 0x8058
|
||||
#define GL_RGB10_A2 0x8059
|
||||
#define GL_RGBA12 0x805A
|
||||
#define GL_RGBA16 0x805B
|
||||
|
||||
/* Utility */
|
||||
#define GL_VENDOR 0x1F00
|
||||
#define GL_RENDERER 0x1F01
|
||||
#define GL_VERSION 0x1F02
|
||||
#define GL_EXTENSIONS 0x1F03
|
||||
|
||||
/* Errors */
|
||||
#define GL_NO_ERROR 0x0
|
||||
#define GL_INVALID_VALUE 0x0501
|
||||
#define GL_INVALID_ENUM 0x0500
|
||||
#define GL_INVALID_OPERATION 0x0502
|
||||
#define GL_STACK_OVERFLOW 0x0503
|
||||
#define GL_STACK_UNDERFLOW 0x0504
|
||||
#define GL_OUT_OF_MEMORY 0x0505
|
||||
|
||||
|
||||
/* OpenGL 1.2 */
|
||||
#define GL_RESCALE_NORMAL 0x803A
|
||||
#define GL_CLAMP_TO_EDGE 0x812F
|
||||
#define GL_MAX_ELEMENTS_VERTICES 0x80E8
|
||||
#define GL_MAX_ELEMENTS_INDICES 0x80E9
|
||||
#define GL_BGR 0x80E0
|
||||
#define GL_BGRA 0x80E1
|
||||
#define GL_UNSIGNED_BYTE_3_3_2 0x8032
|
||||
#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362
|
||||
#define GL_UNSIGNED_SHORT_5_6_5 0x8363
|
||||
#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364
|
||||
#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033
|
||||
#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365
|
||||
#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034
|
||||
#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366
|
||||
#define GL_UNSIGNED_INT_8_8_8_8 0x8035
|
||||
#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367
|
||||
#define GL_UNSIGNED_INT_10_10_10_2 0x8036
|
||||
#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368
|
||||
#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8
|
||||
#define GL_SINGLE_COLOR 0x81F9
|
||||
#define GL_SEPARATE_SPECULAR_COLOR 0x81FA
|
||||
#define GL_TEXTURE_MIN_LOD 0x813A
|
||||
#define GL_TEXTURE_MAX_LOD 0x813B
|
||||
#define GL_TEXTURE_BASE_LEVEL 0x813C
|
||||
#define GL_TEXTURE_MAX_LEVEL 0x813D
|
||||
#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12
|
||||
#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13
|
||||
#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22
|
||||
#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23
|
||||
#define GL_ALIASED_POINT_SIZE_RANGE 0x846D
|
||||
#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* OpenGL 1.2 imaging subset (NOT IMPLEMENTED BY MESA)
|
||||
*/
|
||||
/* GL_EXT_color_table */
|
||||
#define GL_COLOR_TABLE 0x80D0
|
||||
#define GL_POST_CONVOLUTION_COLOR_TABLE 0x80D1
|
||||
#define GL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2
|
||||
#define GL_PROXY_COLOR_TABLE 0x80D3
|
||||
#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4
|
||||
#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5
|
||||
#define GL_COLOR_TABLE_SCALE 0x80D6
|
||||
#define GL_COLOR_TABLE_BIAS 0x80D7
|
||||
#define GL_COLOR_TABLE_FORMAT 0x80D8
|
||||
#define GL_COLOR_TABLE_WIDTH 0x80D9
|
||||
#define GL_COLOR_TABLE_RED_SIZE 0x80DA
|
||||
#define GL_COLOR_TABLE_GREEN_SIZE 0x80DB
|
||||
#define GL_COLOR_TABLE_BLUE_SIZE 0x80DC
|
||||
#define GL_COLOR_TABLE_ALPHA_SIZE 0x80DD
|
||||
#define GL_COLOR_TABLE_LUMINANCE_SIZE 0x80DE
|
||||
#define GL_COLOR_TABLE_INTENSITY_SIZE 0x80DF
|
||||
/* GL_EXT_convolution and GL_HP_convolution_border_modes */
|
||||
#define GL_CONVOLUTION_1D 0x8010
|
||||
#define GL_CONVOLUTION_2D 0x8011
|
||||
#define GL_SEPARABLE_2D 0x8012
|
||||
#define GL_CONVOLUTION_BORDER_MODE 0x8013
|
||||
#define GL_CONVOLUTION_FILTER_SCALE 0x8014
|
||||
#define GL_CONVOLUTION_FILTER_BIAS 0x8015
|
||||
#define GL_REDUCE 0x8016
|
||||
#define GL_CONVOLUTION_FORMAT 0x8017
|
||||
#define GL_CONVOLUTION_WIDTH 0x8018
|
||||
#define GL_CONVOLUTION_HEIGHT 0x8019
|
||||
#define GL_MAX_CONVOLUTION_WIDTH 0x801A
|
||||
#define GL_MAX_CONVOLUTION_HEIGHT 0x801B
|
||||
#define GL_POST_CONVOLUTION_RED_SCALE 0x801C
|
||||
#define GL_POST_CONVOLUTION_GREEN_SCALE 0x801D
|
||||
#define GL_POST_CONVOLUTION_BLUE_SCALE 0x801E
|
||||
#define GL_POST_CONVOLUTION_ALPHA_SCALE 0x801F
|
||||
#define GL_POST_CONVOLUTION_RED_BIAS 0x8020
|
||||
#define GL_POST_CONVOLUTION_GREEN_BIAS 0x8021
|
||||
#define GL_POST_CONVOLUTION_BLUE_BIAS 0x8022
|
||||
#define GL_POST_CONVOLUTION_ALPHA_BIAS 0x8023
|
||||
#define GL_CONSTANT_BORDER 0x8151
|
||||
#define GL_REPLICATE_BORDER 0x8153
|
||||
#define GL_CONVOLUTION_BORDER_COLOR 0x8154
|
||||
/* GL_SGI_color_matrix */
|
||||
#define GL_COLOR_MATRIX 0x80B1
|
||||
#define GL_COLOR_MATRIX_STACK_DEPTH 0x80B2
|
||||
#define GL_MAX_COLOR_MATRIX_STACK_DEPTH 0x80B3
|
||||
#define GL_POST_COLOR_MATRIX_RED_SCALE 0x80B4
|
||||
#define GL_POST_COLOR_MATRIX_GREEN_SCALE 0x80B5
|
||||
#define GL_POST_COLOR_MATRIX_BLUE_SCALE 0x80B6
|
||||
#define GL_POST_COLOR_MATRIX_ALPHA_SCALE 0x80B7
|
||||
#define GL_POST_COLOR_MATRIX_RED_BIAS 0x80B8
|
||||
#define GL_POST_COLOR_MATRIX_GREEN_BIAS 0x80B9
|
||||
#define GL_POST_COLOR_MATRIX_BLUE_BIAS 0x80BA
|
||||
#define GL_POST_COLOR_MATRIX_ALPHA_BIAS 0x80BB
|
||||
/* GL_EXT_histogram */
|
||||
#define GL_HISTOGRAM 0x8024
|
||||
#define GL_PROXY_HISTOGRAM 0x8025
|
||||
#define GL_HISTOGRAM_WIDTH 0x8026
|
||||
#define GL_HISTOGRAM_FORMAT 0x8027
|
||||
#define GL_HISTOGRAM_RED_SIZE 0x8028
|
||||
#define GL_HISTOGRAM_GREEN_SIZE 0x8029
|
||||
#define GL_HISTOGRAM_BLUE_SIZE 0x802A
|
||||
#define GL_HISTOGRAM_ALPHA_SIZE 0x802B
|
||||
#define GL_HISTOGRAM_LUMINANCE_SIZE 0x802C
|
||||
#define GL_HISTOGRAM_SINK 0x802D
|
||||
#define GL_MINMAX 0x802E
|
||||
#define GL_MINMAX_FORMAT 0x802F
|
||||
#define GL_MINMAX_SINK 0x8030
|
||||
#define GL_TABLE_TOO_LARGE 0x8031
|
||||
/* GL_EXT_blend_color, GL_EXT_blend_minmax */
|
||||
#define GL_BLEND_EQUATION 0x8009
|
||||
#define GL_MIN 0x8007
|
||||
#define GL_MAX 0x8008
|
||||
#define GL_FUNC_ADD 0x8006
|
||||
#define GL_FUNC_SUBTRACT 0x800A
|
||||
#define GL_FUNC_REVERSE_SUBTRACT 0x800B
|
||||
#define GL_BLEND_COLOR 0x8005
|
||||
|
||||
|
||||
/* glPush/PopAttrib bits */
|
||||
#define GL_CURRENT_BIT 0x00000001
|
||||
#define GL_POINT_BIT 0x00000002
|
||||
#define GL_LINE_BIT 0x00000004
|
||||
#define GL_POLYGON_BIT 0x00000008
|
||||
#define GL_POLYGON_STIPPLE_BIT 0x00000010
|
||||
#define GL_PIXEL_MODE_BIT 0x00000020
|
||||
#define GL_LIGHTING_BIT 0x00000040
|
||||
#define GL_FOG_BIT 0x00000080
|
||||
#define GL_DEPTH_BUFFER_BIT 0x00000100
|
||||
#define GL_ACCUM_BUFFER_BIT 0x00000200
|
||||
#define GL_STENCIL_BUFFER_BIT 0x00000400
|
||||
#define GL_VIEWPORT_BIT 0x00000800
|
||||
#define GL_TRANSFORM_BIT 0x00001000
|
||||
#define GL_ENABLE_BIT 0x00002000
|
||||
#define GL_COLOR_BUFFER_BIT 0x00004000
|
||||
#define GL_HINT_BIT 0x00008000
|
||||
#define GL_EVAL_BIT 0x00010000
|
||||
#define GL_LIST_BIT 0x00020000
|
||||
#define GL_TEXTURE_BIT 0x00040000
|
||||
#define GL_SCISSOR_BIT 0x00080000
|
||||
#define GL_ALL_ATTRIB_BITS 0x000FFFFF
|
||||
|
||||
|
||||
#define GL_CLIENT_PIXEL_STORE_BIT 0x00000001
|
||||
#define GL_CLIENT_VERTEX_ARRAY_BIT 0x00000002
|
||||
#define GL_ALL_CLIENT_ATTRIB_BITS 0xFFFFFFFF
|
||||
|
||||
/*
|
||||
* GL_ARB_multitexture (ARB extension 1 and OpenGL 1.2.1)
|
||||
*/
|
||||
#define GL_TEXTURE0_ARB 0x84C0
|
||||
#define GL_TEXTURE1_ARB 0x84C1
|
||||
#define GL_TEXTURE2_ARB 0x84C2
|
||||
#define GL_TEXTURE3_ARB 0x84C3
|
||||
#define GL_TEXTURE4_ARB 0x84C4
|
||||
#define GL_TEXTURE5_ARB 0x84C5
|
||||
#define GL_TEXTURE6_ARB 0x84C6
|
||||
#define GL_TEXTURE7_ARB 0x84C7
|
||||
#define GL_TEXTURE8_ARB 0x84C8
|
||||
#define GL_TEXTURE9_ARB 0x84C9
|
||||
#define GL_TEXTURE10_ARB 0x84CA
|
||||
#define GL_TEXTURE11_ARB 0x84CB
|
||||
#define GL_TEXTURE12_ARB 0x84CC
|
||||
#define GL_TEXTURE13_ARB 0x84CD
|
||||
#define GL_TEXTURE14_ARB 0x84CE
|
||||
#define GL_TEXTURE15_ARB 0x84CF
|
||||
#define GL_TEXTURE16_ARB 0x84D0
|
||||
#define GL_TEXTURE17_ARB 0x84D1
|
||||
#define GL_TEXTURE18_ARB 0x84D2
|
||||
#define GL_TEXTURE19_ARB 0x84D3
|
||||
#define GL_TEXTURE20_ARB 0x84D4
|
||||
#define GL_TEXTURE21_ARB 0x84D5
|
||||
#define GL_TEXTURE22_ARB 0x84D6
|
||||
#define GL_TEXTURE23_ARB 0x84D7
|
||||
#define GL_TEXTURE24_ARB 0x84D8
|
||||
#define GL_TEXTURE25_ARB 0x84D9
|
||||
#define GL_TEXTURE26_ARB 0x84DA
|
||||
#define GL_TEXTURE27_ARB 0x84DB
|
||||
#define GL_TEXTURE28_ARB 0x84DC
|
||||
#define GL_TEXTURE29_ARB 0x84DD
|
||||
#define GL_TEXTURE30_ARB 0x84DE
|
||||
#define GL_TEXTURE31_ARB 0x84DF
|
||||
#define GL_ACTIVE_TEXTURE_ARB 0x84E0
|
||||
#define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1
|
||||
#define GL_MAX_TEXTURE_UNITS_ARB 0x84E2
|
||||
|
||||
#define GL_COMBINE 0x8570
|
||||
#define GL_COMBINE_RGB 0x8571
|
||||
#define GL_COMBINE_ALPHA 0x8572
|
||||
#define GL_SOURCE0_RGB 0x8580
|
||||
#define GL_SOURCE1_RGB 0x8581
|
||||
#define GL_SOURCE2_RGB 0x8582
|
||||
#define GL_SOURCE0_ALPHA 0x8588
|
||||
#define GL_SOURCE1_ALPHA 0x8589
|
||||
#define GL_SOURCE2_ALPHA 0x858A
|
||||
#define GL_OPERAND0_RGB 0x8590
|
||||
#define GL_OPERAND1_RGB 0x8591
|
||||
#define GL_OPERAND2_RGB 0x8592
|
||||
#define GL_OPERAND0_ALPHA 0x8598
|
||||
#define GL_OPERAND1_ALPHA 0x8599
|
||||
#define GL_OPERAND2_ALPHA 0x859A
|
||||
#define GL_RGB_SCALE 0x8573
|
||||
#define GL_ADD_SIGNED 0x8574
|
||||
#define GL_INTERPOLATE 0x8575
|
||||
#define GL_SUBTRACT 0x84E7
|
||||
#define GL_CONSTANT 0x8576
|
||||
#define GL_PRIMARY_COLOR 0x8577
|
||||
#define GL_PREVIOUS 0x8578
|
||||
#define GL_DOT3_RGB 0x86AE
|
||||
#define GL_DOT3_RGBA 0x86AF
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // #ifndef _X86UNIX_GL_TYPES_H_
|
147
engine/platformX86UNIX/platformAL.h
Executable file
147
engine/platformX86UNIX/platformAL.h
Executable file
@ -0,0 +1,147 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
#ifndef _PLATFORMAL_H_
|
||||
#define _PLATFORMAL_H_
|
||||
|
||||
#ifndef _PLATFORM_H_
|
||||
#include "platform/platform.h"
|
||||
#endif
|
||||
#define AL_NO_PROTOTYPES
|
||||
#include <al/al.h>
|
||||
#include <al/alc.h>
|
||||
#include <al/alut.h>
|
||||
|
||||
// extra enums for win32/miles implementation
|
||||
enum {
|
||||
// error values
|
||||
AL_CONTEXT_ALREADY_INSTANTIATED = 0xbaadf00d,
|
||||
AL_ENVIRONMENT_ALREADY_INSTANTIATED,
|
||||
AL_UNSUPPORTED,
|
||||
AL_INVALID_BUFFER,
|
||||
AL_ERROR,
|
||||
|
||||
// context extention
|
||||
ALC_PROVIDER,
|
||||
ALC_PROVIDER_COUNT,
|
||||
ALC_PROVIDER_NAME,
|
||||
ALC_SPEAKER,
|
||||
ALC_SPEAKER_COUNT,
|
||||
ALC_SPEAKER_NAME,
|
||||
ALC_BUFFER_DYNAMIC_MEMORY_SIZE,
|
||||
ALC_BUFFER_DYNAMIC_MEMORY_USAGE,
|
||||
ALC_BUFFER_DYNAMIC_COUNT,
|
||||
ALC_BUFFER_MEMORY_USAGE,
|
||||
ALC_BUFFER_COUNT,
|
||||
ALC_BUFFER_LATENCY,
|
||||
|
||||
// misc 3d params
|
||||
AL_MIN_DISTANCE,
|
||||
AL_MAX_DISTANCE,
|
||||
AL_CONE_OUTER_GAIN,
|
||||
|
||||
// relative with pos(0,0,0) won't work for ambient sounds with miles
|
||||
AL_SOURCE_AMBIENT,
|
||||
AL_PAN,
|
||||
|
||||
// other extensions
|
||||
AL_BUFFER_KEEP_RESIDENT,
|
||||
AL_FORMAT_WAVE_EXT,
|
||||
|
||||
// Environment extensions:
|
||||
AL_ENV_EFFECT_VOLUME_EXT,
|
||||
AL_ENV_FLAGS_EXT,
|
||||
AL_ENV_DAMPING_EXT,
|
||||
AL_ENV_ENVIRONMENT_SIZE_EXT,
|
||||
AL_ENV_ROOM_VOLUME_EXT,
|
||||
};
|
||||
|
||||
enum {
|
||||
// sample level environment:
|
||||
AL_ENV_SAMPLE_REVERB_MIX_EXT = 0,
|
||||
AL_ENV_SAMPLE_DIRECT_EXT,
|
||||
AL_ENV_SAMPLE_DIRECT_HF_EXT,
|
||||
AL_ENV_SAMPLE_ROOM_EXT,
|
||||
AL_ENV_SAMPLE_ROOM_HF_EXT,
|
||||
AL_ENV_SAMPLE_OBSTRUCTION_EXT,
|
||||
AL_ENV_SAMPLE_OBSTRUCTION_LF_RATIO_EXT,
|
||||
AL_ENV_SAMPLE_OCCLUSION_EXT,
|
||||
AL_ENV_SAMPLE_OCCLUSION_LF_RATIO_EXT,
|
||||
AL_ENV_SAMPLE_OCCLUSION_ROOM_RATIO_EXT,
|
||||
AL_ENV_SAMPLE_ROOM_ROLLOFF_EXT,
|
||||
AL_ENV_SAMPLE_AIR_ABSORPTION_EXT,
|
||||
AL_ENV_SAMPLE_OUTSIDE_VOLUME_HF_EXT,
|
||||
AL_ENV_SAMPLE_FLAGS_EXT,
|
||||
|
||||
AL_ENV_SAMPLE_COUNT,
|
||||
};
|
||||
|
||||
// room types: same as miles/eax
|
||||
enum {
|
||||
AL_ENVIRONMENT_GENERIC = 0,
|
||||
AL_ENVIRONMENT_PADDEDCELL,
|
||||
AL_ENVIRONMENT_ROOM,
|
||||
AL_ENVIRONMENT_BATHROOM,
|
||||
AL_ENVIRONMENT_LIVINGROOM,
|
||||
AL_ENVIRONMENT_STONEROOM,
|
||||
AL_ENVIRONMENT_AUDITORIUM,
|
||||
AL_ENVIRONMENT_CONCERTHALL,
|
||||
AL_ENVIRONMENT_CAVE,
|
||||
AL_ENVIRONMENT_ARENA,
|
||||
AL_ENVIRONMENT_HANGAR,
|
||||
AL_ENVIRONMENT_CARPETEDHALLWAY,
|
||||
AL_ENVIRONMENT_HALLWAY,
|
||||
AL_ENVIRONMENT_STONECORRIDOR,
|
||||
AL_ENVIRONMENT_ALLEY,
|
||||
AL_ENVIRONMENT_FOREST,
|
||||
AL_ENVIRONMENT_CITY,
|
||||
AL_ENVIRONMENT_MOUNTAINS,
|
||||
AL_ENVIRONMENT_QUARRY,
|
||||
AL_ENVIRONMENT_PLAIN,
|
||||
AL_ENVIRONMENT_PARKINGLOT,
|
||||
AL_ENVIRONMENT_SEWERPIPE,
|
||||
AL_ENVIRONMENT_UNDERWATER,
|
||||
AL_ENVIRONMENT_DRUGGED,
|
||||
AL_ENVIRONMENT_DIZZY,
|
||||
AL_ENVIRONMENT_PSYCHOTIC,
|
||||
|
||||
AL_ENVIRONMENT_COUNT
|
||||
};
|
||||
|
||||
// declare OpenAL functions
|
||||
#define AL_EXTENSION(ext_name) extern bool gDoesSupport_##ext_name;
|
||||
#define AL_FUNCTION(fn_return,fn_name,fn_args) extern fn_return (FN_CDECL *fn_name)fn_args;
|
||||
#define AL_EXT_FUNCTION(ext_name,fn_return,fn_name,fn_args) extern fn_return (FN_CDECL *fn_name)fn_args;
|
||||
#ifndef _OPENALFN_H_
|
||||
#include <openALFn.h>
|
||||
#endif
|
||||
|
||||
namespace Audio
|
||||
{
|
||||
|
||||
bool libraryInit(const char *library);
|
||||
void libraryInitExtensions();
|
||||
void libraryShutdown();
|
||||
|
||||
inline bool doesSupportIASIG()
|
||||
{
|
||||
return gDoesSupport_AL_EXT_IASIG;
|
||||
}
|
||||
|
||||
inline bool doesSupportDynamix()
|
||||
{
|
||||
return gDoesSupport_AL_EXT_DYNAMIX;
|
||||
}
|
||||
|
||||
// helpers
|
||||
F32 DBToLinear(F32 value);
|
||||
F32 linearToDB(F32 value);
|
||||
|
||||
} // end namespace Audio
|
||||
|
||||
|
||||
#endif // _H_PLATFORMAL_
|
188
engine/platformX86UNIX/platformGL.h
Executable file
188
engine/platformX86UNIX/platformGL.h
Executable file
@ -0,0 +1,188 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
#ifndef _PLATFORMGL_H_
|
||||
#define _PLATFORMGL_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define GLAPI extern
|
||||
#define GLAPIENTRY
|
||||
|
||||
#include "platformX86UNIX/gl_types.h"
|
||||
|
||||
#define GL_FUNCTION(fn_return,fn_name,fn_args,fn_value) extern fn_return (*fn_name)fn_args;
|
||||
#include "platform/GLCoreFunc.h"
|
||||
#include "platform/GLExtFunc.h"
|
||||
#undef GL_FUNCTION
|
||||
|
||||
// GLU functions are linked at compile time, except in the dedicated server build
|
||||
#ifndef DEDICATED
|
||||
#define GL_FUNCTION(fn_return,fn_name,fn_args,fn_value) fn_return fn_name fn_args;
|
||||
#else
|
||||
#define GL_FUNCTION(fn_return,fn_name,fn_args,fn_value) extern fn_return (*fn_name)fn_args;
|
||||
#endif
|
||||
#include "platform/GLUFunc.h"
|
||||
#undef GL_FUNCTION
|
||||
|
||||
namespace GLLoader
|
||||
{
|
||||
bool OpenGLInit();
|
||||
void OpenGLShutdown();
|
||||
|
||||
bool OpenGLDLLInit();
|
||||
void OpenGLDLLShutdown();
|
||||
}
|
||||
|
||||
/*
|
||||
* GL state information.
|
||||
*/
|
||||
struct GLState
|
||||
{
|
||||
bool suppARBMultitexture;
|
||||
bool suppEXTblendcolor;
|
||||
bool suppEXTblendminmax;
|
||||
bool suppPackedPixels;
|
||||
bool suppTexEnvAdd;
|
||||
bool suppLockedArrays;
|
||||
bool suppTextureEnvCombine;
|
||||
bool suppVertexArrayRange;
|
||||
bool suppFogCoord;
|
||||
bool suppEdgeClamp;
|
||||
bool suppTextureCompression;
|
||||
bool suppS3TC;
|
||||
bool suppFXT1;
|
||||
bool suppTexAnisotropic;
|
||||
bool suppPalettedTexture;
|
||||
bool suppVertexBuffer;
|
||||
bool suppSwapInterval;
|
||||
unsigned int triCount[4];
|
||||
unsigned int primCount[4];
|
||||
unsigned int primMode; // 0-3
|
||||
|
||||
GLfloat maxAnisotropy;
|
||||
GLint maxTextureUnits;
|
||||
};
|
||||
|
||||
extern GLState gGLState;
|
||||
|
||||
extern bool gOpenGLDisablePT;
|
||||
extern bool gOpenGLDisableCVA;
|
||||
extern bool gOpenGLDisableTEC;
|
||||
extern bool gOpenGLDisableARBMT;
|
||||
extern bool gOpenGLDisableFC;
|
||||
extern bool gOpenGLDisableTCompress;
|
||||
extern bool gOpenGLNoEnvColor;
|
||||
extern float gOpenGLGammaCorrection;
|
||||
extern bool gOpenGLNoDrawArraysAlpha;
|
||||
|
||||
inline void dglSetRenderPrimType(unsigned int type)
|
||||
{
|
||||
gGLState.primMode = type;
|
||||
}
|
||||
|
||||
inline void dglClearPrimMetrics()
|
||||
{
|
||||
for(int i = 0; i < 4; i++)
|
||||
gGLState.triCount[i] = gGLState.primCount[i] = 0;
|
||||
}
|
||||
|
||||
inline bool dglDoesSupportPalettedTexture()
|
||||
{
|
||||
return gGLState.suppPalettedTexture && (gOpenGLDisablePT == false);
|
||||
}
|
||||
|
||||
inline bool dglDoesSupportCompiledVertexArray()
|
||||
{
|
||||
return gGLState.suppLockedArrays && (gOpenGLDisableCVA == false);
|
||||
}
|
||||
|
||||
inline bool dglDoesSupportTextureEnvCombine()
|
||||
{
|
||||
return gGLState.suppTextureEnvCombine && (gOpenGLDisableTEC == false);
|
||||
}
|
||||
|
||||
inline bool dglDoesSupportARBMultitexture()
|
||||
{
|
||||
return gGLState.suppARBMultitexture && (gOpenGLDisableARBMT == false);
|
||||
}
|
||||
|
||||
inline bool dglDoesSupportEXTBlendColor()
|
||||
{
|
||||
return gGLState.suppEXTblendcolor;
|
||||
}
|
||||
|
||||
inline bool dglDoesSupportEXTBlendMinMax()
|
||||
{
|
||||
return gGLState.suppEXTblendminmax;
|
||||
}
|
||||
|
||||
inline bool dglDoesSupportVertexArrayRange()
|
||||
{
|
||||
return gGLState.suppVertexArrayRange;
|
||||
}
|
||||
|
||||
inline bool dglDoesSupportFogCoord()
|
||||
{
|
||||
return gGLState.suppFogCoord && (gOpenGLDisableFC == false);
|
||||
}
|
||||
|
||||
inline bool dglDoesSupportEdgeClamp()
|
||||
{
|
||||
return gGLState.suppEdgeClamp;
|
||||
}
|
||||
|
||||
inline bool dglDoesSupportTextureCompression()
|
||||
{
|
||||
return gGLState.suppTextureCompression && (gOpenGLDisableTCompress == false);
|
||||
}
|
||||
|
||||
inline bool dglDoesSupportS3TC()
|
||||
{
|
||||
return gGLState.suppS3TC;
|
||||
}
|
||||
|
||||
inline bool dglDoesSupportFXT1()
|
||||
{
|
||||
return gGLState.suppFXT1;
|
||||
}
|
||||
|
||||
inline bool dglDoesSupportTexEnvAdd()
|
||||
{
|
||||
return gGLState.suppTexEnvAdd;
|
||||
}
|
||||
|
||||
inline bool dglDoesSupportTexAnisotropy()
|
||||
{
|
||||
return gGLState.suppTexAnisotropic;
|
||||
}
|
||||
|
||||
inline bool dglDoesSupportVertexBuffer()
|
||||
{
|
||||
return gGLState.suppVertexBuffer;
|
||||
}
|
||||
|
||||
inline GLfloat dglGetMaxAnisotropy()
|
||||
{
|
||||
return gGLState.maxAnisotropy;
|
||||
}
|
||||
|
||||
inline GLint dglGetMaxTextureUnits()
|
||||
{
|
||||
if (dglDoesSupportARBMultitexture())
|
||||
return gGLState.maxTextureUnits;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
49
engine/platformX86UNIX/platformX86UNIX.h
Executable file
49
engine/platformX86UNIX/platformX86UNIX.h
Executable file
@ -0,0 +1,49 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
#ifndef _PLATFORMX86UNIX_H_
|
||||
#define _PLATFORMX86UNIX_H_
|
||||
|
||||
#ifndef _PLATFORM_H_
|
||||
#include "platform/platform.h"
|
||||
#endif
|
||||
#ifndef _EVENT_H_
|
||||
#include "platform/event.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
// these will be used to construct the user preference directory where
|
||||
// created files will be stored (~/PREF_DIR_ROOT/PREF_DIR_GAME_NAME)
|
||||
#define PREF_DIR_ROOT ".garagegames"
|
||||
#define PREF_DIR_GAME_NAME "torqueDemo"
|
||||
|
||||
// event codes for custom SDL events
|
||||
const S32 TORQUE_SETVIDEOMODE = 1;
|
||||
|
||||
extern bool GL_EXT_Init( void );
|
||||
|
||||
extern void PlatformBlitInit( void );
|
||||
|
||||
// Process Control functions
|
||||
void Cleanup(bool minimal=false);
|
||||
void ImmediateShutdown(S32 exitCode, S32 signalNum = 0);
|
||||
void ProcessControlInit();
|
||||
bool AcquireProcessMutex(const char *mutexName);
|
||||
|
||||
// Utility functions
|
||||
// Convert a string to lowercase in place
|
||||
char *strtolwr(char* str);
|
||||
|
||||
void DisplayErrorAlert(const char* errMsg, bool showSDLError = true);
|
||||
|
||||
// Just like strstr, except case insensitive
|
||||
// (Found this function at http://www.codeguru.com/string/stristr.html)
|
||||
extern char *stristr(char *szStringToBeSearched, const char *szSubstringToSearchFor);
|
||||
|
||||
#endif
|
50
engine/platformX86UNIX/x86UNIXAsmBlit.cc
Executable file
50
engine/platformX86UNIX/x86UNIXAsmBlit.cc
Executable file
@ -0,0 +1,50 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
#include "terrain/terrData.h"
|
||||
#include "math/mMath.h"
|
||||
#include "dgl/dgl.h"
|
||||
#include "dgl/gBitmap.h"
|
||||
#include "terrain/terrRender.h"
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void bitmapExtrude5551_asm(const void *srcMip, void *mip, U32 height, U32 width)
|
||||
{
|
||||
const U16 *src = (const U16 *) srcMip;
|
||||
U16 *dst = (U16 *) mip;
|
||||
U32 stride = width << 1;
|
||||
|
||||
for(U32 y = 0; y < height; y++)
|
||||
{
|
||||
for(U32 x = 0; x < width; x++)
|
||||
{
|
||||
U32 a = src[0];
|
||||
U32 b = src[1];
|
||||
U32 c = src[stride];
|
||||
U32 d = src[stride+1];
|
||||
dst[x] = ((((a >> 11) + (b >> 11) + (c >> 11) + (d >> 11)) >> 2) << 11) |
|
||||
((( ((a >> 6) & 0x1f) + ((b >> 6) & 0x1f) + ((c >> 6) & 0x1f) + ((d >> 6) & 0x1F) ) >> 2) << 6) |
|
||||
((( ((a >> 1) & 0x1F) + ((b >> 1) & 0x1F) + ((c >> 1) & 0x1f) + ((d >> 1) & 0x1f)) >> 2) << 1);
|
||||
src += 2;
|
||||
}
|
||||
src += stride;
|
||||
dst += width;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void PlatformBlitInit()
|
||||
{
|
||||
bitmapExtrude5551 = bitmapExtrude5551_asm;
|
||||
bitmapExtrudeRGB = bitmapExtrudeRGB_c;
|
||||
|
||||
if (Platform::SystemInfo.processor.properties & CPU_PROP_MMX)
|
||||
{
|
||||
// JMQ: haven't bothered porting mmx bitmap funcs because they don't
|
||||
// seem to offer a big performance boost right now.
|
||||
}
|
||||
}
|
138
engine/platformX86UNIX/x86UNIXCPUInfo.cc
Executable file
138
engine/platformX86UNIX/x86UNIXCPUInfo.cc
Executable file
@ -0,0 +1,138 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "platformX86UNIX/platformX86UNIX.h"
|
||||
#include "console/console.h"
|
||||
#include "core/stringTable.h"
|
||||
#include <math.h>
|
||||
|
||||
Platform::SystemInfo_struct Platform::SystemInfo;
|
||||
|
||||
extern void PlatformBlitInit();
|
||||
extern void SetProcessorInfo(Platform::SystemInfo_struct::Processor& pInfo,
|
||||
char* vendor, U32 processor, U32 properties); // platform/platformCPU.cc
|
||||
|
||||
// asm cpu detection routine from platform code
|
||||
extern "C"
|
||||
{
|
||||
void detectX86CPUInfo(char *vendor, U32 *processor, U32 *properties);
|
||||
}
|
||||
|
||||
/* used in the asm */
|
||||
static U32 time[2];
|
||||
static U32 clockticks = 0;
|
||||
static char vendor[13] = {0,};
|
||||
static U32 properties = 0;
|
||||
static U32 processor = 0;
|
||||
|
||||
void Processor::init()
|
||||
{
|
||||
// Reference:
|
||||
// www.cyrix.com
|
||||
// www.amd.com
|
||||
// www.intel.com
|
||||
// http://developer.intel.com/design/PentiumII/manuals/24512701.pdf
|
||||
Platform::SystemInfo.processor.type = CPU_X86Compatible;
|
||||
Platform::SystemInfo.processor.name = StringTable->insert("Unknown x86 Compatible");
|
||||
Platform::SystemInfo.processor.mhz = 0;
|
||||
Platform::SystemInfo.processor.properties = CPU_PROP_C;
|
||||
|
||||
clockticks = properties = processor = 0;
|
||||
dStrcpy(vendor, "");
|
||||
|
||||
detectX86CPUInfo(vendor, &processor, &properties);
|
||||
SetProcessorInfo(Platform::SystemInfo.processor,
|
||||
vendor, processor, properties);
|
||||
|
||||
//--------------------------------------
|
||||
// if RDTSC support calculate the aproximate Mhz of the CPU
|
||||
if (Platform::SystemInfo.processor.properties & CPU_PROP_RDTSC &&
|
||||
Platform::SystemInfo.processor.properties & CPU_PROP_FPU)
|
||||
{
|
||||
const U32 MS_INTERVAL = 750;
|
||||
|
||||
#if defined(TORQUE_COMPILER_GCC) && ((__GNUC__ >= 3) && (__GNUC_MINOR__ >=4))
|
||||
asm("rdtsc" : "=a" (timeLo), "=d" (timeHi));
|
||||
#else
|
||||
__asm__(
|
||||
"pushl %eax\n"
|
||||
"pushl %edx\n"
|
||||
"rdtsc\n"
|
||||
"movl %eax, (time)\n"
|
||||
"movl %edx, (time+4)\n"
|
||||
"popl %edx\n"
|
||||
"popl %eax\n"
|
||||
);
|
||||
#endif
|
||||
U32 ms = Platform::getRealMilliseconds();
|
||||
while ( Platform::getRealMilliseconds() < ms+MS_INTERVAL )
|
||||
{ /* empty */ }
|
||||
ms = Platform::getRealMilliseconds()-ms;
|
||||
#if defined(TORQUE_COMPILER_GCC) && ((__GNUC__ >= 3) && (__GNUC_MINOR__ >= 4))
|
||||
asm(
|
||||
"pushl %eax\n"
|
||||
"pushl %edx\n"
|
||||
"rdtsc\n"
|
||||
"sub (timeHi), %edx\n"
|
||||
"sbb (timeLo), %eax\n"
|
||||
"mov %eax, (clockticks)\n"
|
||||
"popl %edx\n"
|
||||
"popl %eax\n"
|
||||
);
|
||||
#else
|
||||
asm(
|
||||
"pushl %eax\n"
|
||||
"pushl %edx\n"
|
||||
"rdtsc\n"
|
||||
"sub (time+4), %edx\n"
|
||||
"sbb (time), %eax\n"
|
||||
"mov %eax, (clockticks)\n"
|
||||
"popl %edx\n"
|
||||
"popl %eax\n"
|
||||
);
|
||||
#endif
|
||||
U32 mhz = static_cast<U32>(F32(clockticks) / F32(ms) / 1000.0f);
|
||||
|
||||
// catch-22 the timing method used above to calc Mhz is generally
|
||||
// wrong by a few percent so we want to round to the nearest clock
|
||||
// multiple but we also want to be careful to not touch overclocked
|
||||
// results
|
||||
|
||||
// measure how close the Raw Mhz number is to the center of each clock
|
||||
// bucket
|
||||
U32 bucket25 = mhz % 25;
|
||||
U32 bucket33 = mhz % 33;
|
||||
U32 bucket50 = mhz % 50;
|
||||
|
||||
if (bucket50 < 8 || bucket50 > 42)
|
||||
Platform::SystemInfo.processor.mhz =
|
||||
U32((mhz+(50.0f/2.0f))/50.0f) * 50;
|
||||
else if (bucket25 < 5 || bucket25 > 20)
|
||||
Platform::SystemInfo.processor.mhz =
|
||||
U32((mhz+(25.0f/2.0f))/25.0f) * 25;
|
||||
else if (bucket33 < 5 || bucket33 > 28)
|
||||
Platform::SystemInfo.processor.mhz =
|
||||
U32((mhz+(33.0f/2.0f))/33.0f) * 33;
|
||||
else
|
||||
Platform::SystemInfo.processor.mhz = U32(mhz);
|
||||
}
|
||||
|
||||
Con::printf("Processor Init:");
|
||||
Con::printf(" %s, %d Mhz", Platform::SystemInfo.processor.name, Platform::SystemInfo.processor.mhz);
|
||||
if (Platform::SystemInfo.processor.properties & CPU_PROP_FPU)
|
||||
Con::printf(" FPU detected");
|
||||
if (Platform::SystemInfo.processor.properties & CPU_PROP_MMX)
|
||||
Con::printf(" MMX detected");
|
||||
if (Platform::SystemInfo.processor.properties & CPU_PROP_3DNOW)
|
||||
Con::printf(" 3DNow detected");
|
||||
if (Platform::SystemInfo.processor.properties & CPU_PROP_SSE)
|
||||
Con::printf(" SSE detected");
|
||||
Con::printf(" ");
|
||||
|
||||
PlatformBlitInit();
|
||||
}
|
378
engine/platformX86UNIX/x86UNIXConsole.cc
Executable file
378
engine/platformX86UNIX/x86UNIXConsole.cc
Executable file
@ -0,0 +1,378 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
#include "platformX86UNIX/platformX86UNIX.h"
|
||||
#include "platformX86UNIX/x86UNIXStdConsole.h"
|
||||
#include "platformX86UNIX/x86UNIXUtils.h"
|
||||
#include "platform/event.h"
|
||||
#include "platform/gameInterface.h"
|
||||
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <stdarg.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
StdConsole *stdConsole = NULL;
|
||||
|
||||
ConsoleFunction(enableWinConsole, void, 2, 2, "enableWinConsole(bool);")
|
||||
{
|
||||
argc;
|
||||
if (stdConsole)
|
||||
stdConsole->enable(dAtob(argv[1]));
|
||||
}
|
||||
|
||||
void StdConsole::create()
|
||||
{
|
||||
if (stdConsole == NULL)
|
||||
stdConsole = new StdConsole();
|
||||
}
|
||||
|
||||
void StdConsole::destroy()
|
||||
{
|
||||
if (stdConsole && stdConsole->isEnabled())
|
||||
stdConsole->enable(false);
|
||||
|
||||
delete stdConsole;
|
||||
stdConsole = NULL;
|
||||
}
|
||||
|
||||
static void signalHandler(int sigtype)
|
||||
{
|
||||
if (sigtype == SIGCONT && stdConsole != NULL)
|
||||
stdConsole->resetTerminal();
|
||||
}
|
||||
|
||||
void StdConsole::resetTerminal()
|
||||
{
|
||||
if (stdConsoleEnabled)
|
||||
{
|
||||
/* setup the proper terminal modes */
|
||||
struct termios termModes;
|
||||
tcgetattr(stdIn, &termModes);
|
||||
termModes.c_lflag &= ~ICANON; // enable non-canonical mode
|
||||
termModes.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHOKE);
|
||||
termModes.c_cc[VMIN] = 0;
|
||||
termModes.c_cc[VTIME] = 5;
|
||||
tcsetattr(stdIn, TCSAFLUSH, &termModes);
|
||||
}
|
||||
}
|
||||
|
||||
void StdConsole::enable(bool enabled)
|
||||
{
|
||||
if (enabled && !stdConsoleEnabled)
|
||||
{
|
||||
stdConsoleEnabled = true;
|
||||
|
||||
// install signal handler for sigcont
|
||||
signal(SIGCONT, &signalHandler);
|
||||
|
||||
// save the terminal state
|
||||
if (originalTermState == NULL)
|
||||
originalTermState = new termios;
|
||||
|
||||
tcgetattr(stdIn, originalTermState);
|
||||
|
||||
// put the terminal into our preferred mode
|
||||
resetTerminal();
|
||||
|
||||
printf("%s", Con::getVariable("Con::Prompt"));
|
||||
|
||||
}
|
||||
else if (!enabled && stdConsoleEnabled)
|
||||
{
|
||||
stdConsoleEnabled = false;
|
||||
|
||||
// uninstall signal handler
|
||||
signal(SIGCONT, SIG_DFL);
|
||||
|
||||
// reset the original terminal state
|
||||
if (originalTermState != NULL)
|
||||
tcsetattr(stdIn, TCSANOW, originalTermState);
|
||||
}
|
||||
}
|
||||
|
||||
bool StdConsole::isEnabled()
|
||||
{
|
||||
if ( stdConsole )
|
||||
return stdConsole->stdConsoleEnabled;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void stdConsoleConsumer(ConsoleLogEntry::Level, const char *line)
|
||||
{
|
||||
stdConsole->processConsoleLine(line);
|
||||
}
|
||||
|
||||
StdConsole::StdConsole()
|
||||
{
|
||||
for (S32 iIndex = 0; iIndex < MAX_CMDS; iIndex ++)
|
||||
rgCmds[iIndex][0] = '\0';
|
||||
|
||||
stdOut = dup(1);
|
||||
stdIn = dup(0);
|
||||
stdErr = dup(2);
|
||||
|
||||
iCmdIndex = 0;
|
||||
stdConsoleEnabled = false;
|
||||
Con::addConsumer(stdConsoleConsumer);
|
||||
inpos = 0;
|
||||
lineOutput = false;
|
||||
inBackground = false;
|
||||
originalTermState = NULL;
|
||||
}
|
||||
|
||||
StdConsole::~StdConsole()
|
||||
{
|
||||
Con::removeConsumer(stdConsoleConsumer);
|
||||
|
||||
if (stdConsoleEnabled)
|
||||
enable(false);
|
||||
|
||||
if (originalTermState != NULL)
|
||||
{
|
||||
delete originalTermState;
|
||||
originalTermState = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void StdConsole::printf(const char *s, ...)
|
||||
{
|
||||
// Get the line into a buffer.
|
||||
static const int BufSize = 4096;
|
||||
static char buffer[BufSize];
|
||||
va_list args;
|
||||
va_start(args, s);
|
||||
vsnprintf(buffer, BufSize, s, args);
|
||||
// Replace tabs with carats, like the "real" console does.
|
||||
char *pos = buffer;
|
||||
while (*pos) {
|
||||
if (*pos == '\t') {
|
||||
*pos = '^';
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
// Axe the color characters.
|
||||
Con::stripColorChars(buffer);
|
||||
// Print it.
|
||||
write(stdOut, buffer, strlen(buffer));
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
void StdConsole::processConsoleLine(const char *consoleLine)
|
||||
{
|
||||
if(stdConsoleEnabled)
|
||||
{
|
||||
inbuf[inpos] = 0;
|
||||
if(lineOutput)
|
||||
printf("%s\n", consoleLine);
|
||||
else
|
||||
printf("%c%s\n%s%s", '\r', consoleLine, Con::getVariable("Con::Prompt"), inbuf);
|
||||
}
|
||||
}
|
||||
|
||||
void StdConsole::process()
|
||||
{
|
||||
if(stdConsoleEnabled)
|
||||
{
|
||||
//U16 key;
|
||||
char typedData[64]; // damn, if you can type this fast... :-D
|
||||
|
||||
if (UUtils->inBackground())
|
||||
// we don't have the terminal
|
||||
inBackground = true;
|
||||
else
|
||||
{
|
||||
// if we were in the background, reset the terminal
|
||||
if (inBackground)
|
||||
resetTerminal();
|
||||
inBackground = false;
|
||||
}
|
||||
|
||||
// see if stdIn has any input waiting
|
||||
// mojo for select call
|
||||
fd_set rfds;
|
||||
struct timeval tv;
|
||||
int retval;
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(stdIn, &rfds);
|
||||
// don't wait at all in select
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
int numEvents = select(stdIn+1, &rfds, NULL, NULL, &tv);
|
||||
if (numEvents <= 0)
|
||||
// no data available
|
||||
return;
|
||||
|
||||
numEvents = read(stdIn, typedData, 64);
|
||||
if (numEvents == -1)
|
||||
return;
|
||||
|
||||
typedData[numEvents] = '\0';
|
||||
if (numEvents > 0)
|
||||
{
|
||||
char outbuf[512];
|
||||
S32 outpos = 0;
|
||||
|
||||
for (int i = 0; i < numEvents; i++)
|
||||
{
|
||||
switch(typedData[i])
|
||||
{
|
||||
case 8:
|
||||
case 127:
|
||||
/* backspace */
|
||||
if (inpos > 0)
|
||||
{
|
||||
outbuf[outpos++] = '\b';
|
||||
outbuf[outpos++] = ' ';
|
||||
outbuf[outpos++] = '\b';
|
||||
inpos--;
|
||||
}
|
||||
break;
|
||||
|
||||
// XXX Don't know if we can detect shift-TAB. So, only handling
|
||||
// TAB for now.
|
||||
|
||||
case '\t':
|
||||
// In the output buffer, we're going to have to erase the current line (in case
|
||||
// we're cycling through various completions) and write out the whole input
|
||||
// buffer, so (inpos * 3) + complen <= 512. Should be OK. The input buffer is
|
||||
// also 512 chars long so that constraint will also be fine for the input buffer.
|
||||
{
|
||||
// Erase the current line.
|
||||
U32 i;
|
||||
for (i = 0; i < inpos; i++) {
|
||||
outbuf[outpos++] = '\b';
|
||||
outbuf[outpos++] = ' ';
|
||||
outbuf[outpos++] = '\b';
|
||||
}
|
||||
// Modify the input buffer with the completion.
|
||||
U32 maxlen = 512 - (inpos * 3);
|
||||
inpos = Con::tabComplete(inbuf, inpos, maxlen, true);
|
||||
// Copy the input buffer to the output.
|
||||
for (i = 0; i < inpos; i++) {
|
||||
outbuf[outpos++] = inbuf[i];
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case '\n':
|
||||
/* new line */
|
||||
outbuf[outpos++] = '\n';
|
||||
|
||||
inbuf[inpos] = 0;
|
||||
outbuf[outpos] = 0;
|
||||
printf("%s", outbuf);
|
||||
|
||||
S32 eventSize;
|
||||
eventSize = 1;
|
||||
|
||||
dStrcpy(postEvent.data, inbuf);
|
||||
postEvent.size = eventSize + dStrlen(inbuf) + 1;
|
||||
Game->postEvent(postEvent);
|
||||
// If we've gone off the end of our array, wrap
|
||||
// back to the beginning
|
||||
if (iCmdIndex >= MAX_CMDS)
|
||||
iCmdIndex %= MAX_CMDS;
|
||||
|
||||
// Put the new command into the array
|
||||
strcpy(rgCmds[iCmdIndex ++], inbuf);
|
||||
|
||||
printf("%s", Con::getVariable("Con::Prompt"));
|
||||
inpos = outpos = 0;
|
||||
break;
|
||||
case 27:
|
||||
// JMQTODO: are these magic numbers keyboard map specific?
|
||||
if (typedData[i+1] == 91 || typedData[i+1] == 79)
|
||||
{
|
||||
i += 2;
|
||||
// an arrow key was pressed.
|
||||
switch(typedData[i])
|
||||
{
|
||||
case 'A':
|
||||
/* up arrow */
|
||||
// Go to the previous command in the cyclic array
|
||||
if ((-- iCmdIndex) < 0)
|
||||
iCmdIndex = MAX_CMDS - 1;
|
||||
|
||||
// If this command isn't empty ...
|
||||
if (rgCmds[iCmdIndex][0] != '\0')
|
||||
{
|
||||
// Obliterate current displayed text
|
||||
for (S32 i = outpos = 0; i < inpos; i ++)
|
||||
{
|
||||
outbuf[outpos++] = '\b';
|
||||
outbuf[outpos++] = ' ';
|
||||
outbuf[outpos++] = '\b';
|
||||
}
|
||||
|
||||
// Copy command into command and display buffers
|
||||
for (inpos = 0; inpos < (S32)strlen(rgCmds[iCmdIndex]); inpos++, outpos++)
|
||||
{
|
||||
outbuf[outpos] = rgCmds[iCmdIndex][inpos];
|
||||
inbuf [inpos ] = rgCmds[iCmdIndex][inpos];
|
||||
}
|
||||
}
|
||||
// If previous is empty, stay on current command
|
||||
else if ((++ iCmdIndex) >= MAX_CMDS)
|
||||
{
|
||||
iCmdIndex = 0;
|
||||
}
|
||||
break;
|
||||
case 'B':
|
||||
/* down arrow */
|
||||
// Go to the next command in the command array, if
|
||||
// it isn't empty
|
||||
if (rgCmds[iCmdIndex][0] != '\0' && (++ iCmdIndex) >= MAX_CMDS)
|
||||
iCmdIndex = 0;
|
||||
|
||||
// Obliterate current displayed text
|
||||
for (S32 i = outpos = 0; i < inpos; i ++)
|
||||
{
|
||||
outbuf[outpos++] = '\b';
|
||||
outbuf[outpos++] = ' ';
|
||||
outbuf[outpos++] = '\b';
|
||||
}
|
||||
|
||||
// Copy command into command and display buffers
|
||||
for (inpos = 0; inpos < (S32)strlen(rgCmds[iCmdIndex]); inpos++, outpos++)
|
||||
{
|
||||
outbuf[outpos] = rgCmds[iCmdIndex][inpos];
|
||||
inbuf [inpos ] = rgCmds[iCmdIndex][inpos];
|
||||
}
|
||||
break;
|
||||
case 'C':
|
||||
/* right arrow */
|
||||
break;
|
||||
case 'D':
|
||||
/* left arrow */
|
||||
break;
|
||||
}
|
||||
// read again to get rid of a bad char.
|
||||
//read(stdIn, &key, sizeof(char));
|
||||
break;
|
||||
} else {
|
||||
inbuf[inpos++] = typedData[i];
|
||||
outbuf[outpos++] = typedData[i];
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
inbuf[inpos++] = typedData[i];
|
||||
outbuf[outpos++] = typedData[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (outpos)
|
||||
{
|
||||
outbuf[outpos] = 0;
|
||||
printf("%s", outbuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
95
engine/platformX86UNIX/x86UNIXDedicatedStub.cc
Executable file
95
engine/platformX86UNIX/x86UNIXDedicatedStub.cc
Executable file
@ -0,0 +1,95 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
// GL stubs
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
#include "platformX86UNIX/platformGL.h"
|
||||
#include "platform/platformAL.h"
|
||||
#include "platform/platformInput.h"
|
||||
|
||||
// declare stub functions
|
||||
#define GL_FUNCTION(fn_return, fn_name, fn_args, fn_value) fn_return stub_##fn_name fn_args{ fn_value }
|
||||
#include "platform/GLCoreFunc.h"
|
||||
#include "platform/GLExtFunc.h"
|
||||
#include "platform/GLUFunc.h"
|
||||
#undef GL_FUNCTION
|
||||
|
||||
// point gl function pointers at stub functions
|
||||
#define GL_FUNCTION(fn_return,fn_name,fn_args, fn_value) fn_return (*fn_name)fn_args = stub_##fn_name;
|
||||
#include "platform/GLCoreFunc.h"
|
||||
#include "platform/GLExtFunc.h"
|
||||
#include "platform/GLUFunc.h"
|
||||
#undef GL_FUNCTION
|
||||
|
||||
GLState gGLState;
|
||||
bool gOpenGLDisablePT = false;
|
||||
bool gOpenGLDisableCVA = false;
|
||||
bool gOpenGLDisableTEC = false;
|
||||
bool gOpenGLDisableARBMT = false;
|
||||
bool gOpenGLDisableFC = false;
|
||||
bool gOpenGLDisableTCompress = false;
|
||||
bool gOpenGLNoEnvColor = false;
|
||||
float gOpenGLGammaCorrection = 0.5;
|
||||
bool gOpenGLNoDrawArraysAlpha = false;
|
||||
|
||||
// AL stubs
|
||||
//#include <al/altypes.h>
|
||||
///#include <al/alctypes.h>
|
||||
//#define INITGUID
|
||||
//#include <al/eaxtypes.h>
|
||||
|
||||
// Define the OpenAL and Extension Stub functions
|
||||
#define AL_FUNCTION(fn_return, fn_name, fn_args, fn_value) fn_return stub_##fn_name fn_args{ fn_value }
|
||||
#include <al/al_func.h>
|
||||
#include <al/alc_func.h>
|
||||
#include <al/eax_func.h>
|
||||
#undef AL_FUNCTION
|
||||
|
||||
|
||||
// Declare the OpenAL and Extension Function pointers
|
||||
// And initialize them to the stub functions
|
||||
#define AL_FUNCTION(fn_return,fn_name,fn_args, fn_value) fn_return (*fn_name)fn_args = stub_##fn_name;
|
||||
#include <al/al_func.h>
|
||||
#include <al/alc_func.h>
|
||||
#include <al/eax_func.h>
|
||||
#undef AL_FUNCTION
|
||||
|
||||
namespace Audio
|
||||
{
|
||||
bool OpenALDLLInit() { return false; }
|
||||
void OpenALDLLShutdown() {}
|
||||
}
|
||||
|
||||
// Platform Stubs
|
||||
const char* Platform::getClipboard() { return ""; }
|
||||
bool Platform::setClipboard(const char *text) { return false; }
|
||||
GFont *createFont(const char *name, dsize_t size) { return NULL; }
|
||||
void PlatformBlitInit( void ) {}
|
||||
|
||||
// #include <X11/Xlib.h>
|
||||
|
||||
// void NotifySelectionEvent(XEvent& event)
|
||||
// {
|
||||
// }
|
||||
|
||||
// Input stubs
|
||||
void Input::init() {}
|
||||
void Input::destroy() {}
|
||||
bool Input::enable() { return false; }
|
||||
void Input::disable() {}
|
||||
void Input::activate() {}
|
||||
void Input::deactivate() {}
|
||||
void Input::reactivate() {}
|
||||
U16 Input::getAscii( U16 keyCode, KEY_STATE keyState ) { return 0; }
|
||||
U16 Input::getKeyCode( U16 asciiCode ) { return 0; }
|
||||
bool Input::isEnabled() { return false; }
|
||||
bool Input::isActive() { return false; }
|
||||
void Input::process() {}
|
||||
InputManager* Input::getManager() { return NULL; }
|
1135
engine/platformX86UNIX/x86UNIXFileio.cc
Executable file
1135
engine/platformX86UNIX/x86UNIXFileio.cc
Executable file
File diff suppressed because it is too large
Load Diff
1
engine/platformX86UNIX/x86UNIXFont.cc
Executable file
1
engine/platformX86UNIX/x86UNIXFont.cc
Executable file
File diff suppressed because one or more lines are too long
376
engine/platformX86UNIX/x86UNIXGL.cc
Executable file
376
engine/platformX86UNIX/x86UNIXGL.cc
Executable file
@ -0,0 +1,376 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
#include "platformX86UNIX/platformGL.h"
|
||||
#include "platformX86UNIX/platformX86UNIX.h"
|
||||
#include "console/console.h"
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <SDL/SDL.h>
|
||||
|
||||
// declare stub functions
|
||||
#define GL_FUNCTION(fn_return, fn_name, fn_args, fn_value) fn_return stub_##fn_name fn_args{ fn_value }
|
||||
#include "platform/GLCoreFunc.h"
|
||||
#include "platform/GLExtFunc.h"
|
||||
#undef GL_FUNCTION
|
||||
|
||||
// point gl function pointers at stub functions
|
||||
#define GL_FUNCTION(fn_return,fn_name,fn_args, fn_value) fn_return (*fn_name)fn_args = stub_##fn_name;
|
||||
#include "platform/GLCoreFunc.h"
|
||||
#include "platform/GLExtFunc.h"
|
||||
#undef GL_FUNCTION
|
||||
|
||||
static void* dlHandle = NULL;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
//bind functions for each function prototype
|
||||
//------------------------------------------------------------------
|
||||
|
||||
//GL_EXT/ARB
|
||||
enum {
|
||||
ARB_multitexture = BIT(0),
|
||||
ARB_texture_compression = BIT(1),
|
||||
EXT_compiled_vertex_array = BIT(2),
|
||||
EXT_fog_coord = BIT(3),
|
||||
EXT_paletted_texture = BIT(4),
|
||||
NV_vertex_array_range = BIT(5),
|
||||
EXT_blend_color = BIT(6),
|
||||
EXT_blend_minmax = BIT(7)
|
||||
};
|
||||
|
||||
//WGL_ARB
|
||||
enum {
|
||||
WGL_ARB_extensions_string = BIT(0),
|
||||
WGL_EXT_swap_control = BIT(1),
|
||||
WGL_3DFX_gamma_control = BIT(2)
|
||||
};
|
||||
|
||||
|
||||
static bool isFnOk( const char *name)
|
||||
{
|
||||
bool ok = false;
|
||||
|
||||
// JMQ: these are specific to torque's d3d->gl wrapper. They are not used under linux.
|
||||
if (dStrcmp(name, "glAvailableVertexBufferEXT")==0)
|
||||
ok = true;
|
||||
else if (dStrcmp(name, "glAllocateVertexBufferEXT")==0)
|
||||
ok = true;
|
||||
else if (dStrcmp(name, "glLockVertexBufferEXT")==0)
|
||||
ok = true;
|
||||
else if (dStrcmp(name, "glUnlockVertexBufferEXT")==0)
|
||||
ok = true;
|
||||
else if (dStrcmp(name, "glSetVertexBufferEXT")==0)
|
||||
ok = true;
|
||||
else if (dStrcmp(name, "glOffsetVertexBufferEXT")==0)
|
||||
ok = true;
|
||||
else if (dStrcmp(name, "glFillVertexBufferEXT")==0)
|
||||
ok = true;
|
||||
else if (dStrcmp(name, "glFreeVertexBufferEXT")==0)
|
||||
ok = true;
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
//bind functions for each function prototype
|
||||
//------------------------------------------------------------------
|
||||
static bool bindGLFunction( void *&fnAddress, const char *name )
|
||||
{
|
||||
void* addr = (void*)SDL_GL_GetProcAddress(name);
|
||||
bool ok = (bool)addr;
|
||||
if( !ok )
|
||||
{
|
||||
if (!isFnOk(name))
|
||||
Con::errorf(ConsoleLogEntry::General, " Missing OpenGL function '%s'", name);
|
||||
else
|
||||
ok = true;
|
||||
}
|
||||
else
|
||||
fnAddress = addr;
|
||||
return ok;
|
||||
}
|
||||
|
||||
static bool bindEXTFunction( void *&fnAddress, const char *name )
|
||||
{
|
||||
void* addr = (void*)SDL_GL_GetProcAddress(name);
|
||||
if( !addr )
|
||||
Con::errorf(ConsoleLogEntry::General, " Missing OpenGL extension '%s'", name);
|
||||
else
|
||||
fnAddress = addr;
|
||||
return (addr != NULL);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
//binds for each function group
|
||||
//------------------------------------------------------------------
|
||||
static bool bindGLFunctions()
|
||||
{
|
||||
bool result = true;
|
||||
#define GL_FUNCTION(fn_return, fn_name, fn_args, fn_value) \
|
||||
result &= bindGLFunction( *(void**)&fn_name, #fn_name);
|
||||
#include "platform/GLCoreFunc.h"
|
||||
#undef GL_FUNCTION
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool bindEXTFunctions(U32 extMask)
|
||||
{
|
||||
bool result = true;
|
||||
|
||||
#define GL_GROUP_BEGIN( flag ) \
|
||||
if( extMask & flag ) {
|
||||
#define GL_GROUP_END() }
|
||||
|
||||
#define GL_FUNCTION(fn_return, fn_name, fn_args, fn_value) \
|
||||
result &= bindEXTFunction( *(void**)&fn_name, #fn_name);
|
||||
#include "platform/GLExtFunc.h"
|
||||
#undef GL_FUNCTION
|
||||
|
||||
#undef GL_GROUP_BEGIN
|
||||
#undef GL_GROUP_END
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void unbindGLFunctions()
|
||||
{
|
||||
// point gl function pointers at stub functions
|
||||
#define GL_FUNCTION(fn_return, fn_name, fn_args, fn_value) fn_name = stub_##fn_name;
|
||||
#include "platform/GLCoreFunc.h"
|
||||
#include "platform/GLExtFunc.h"
|
||||
#undef GL_FUNCTION
|
||||
}
|
||||
|
||||
namespace GLLoader
|
||||
{
|
||||
|
||||
bool OpenGLInit()
|
||||
{
|
||||
return OpenGLDLLInit();
|
||||
}
|
||||
|
||||
void OpenGLShutdown()
|
||||
{
|
||||
OpenGLDLLShutdown();
|
||||
}
|
||||
|
||||
bool OpenGLDLLInit()
|
||||
{
|
||||
OpenGLDLLShutdown();
|
||||
|
||||
// load libGL.so
|
||||
if (SDL_GL_LoadLibrary("libGL.so") == -1 &&
|
||||
SDL_GL_LoadLibrary("libGL.so.1") == -1)
|
||||
{
|
||||
Con::errorf("Error loading GL library: %s", SDL_GetError());
|
||||
return false;
|
||||
}
|
||||
|
||||
// bind functions
|
||||
if (!bindGLFunctions())
|
||||
{
|
||||
Con::errorf("Error binding GL functions");
|
||||
OpenGLDLLShutdown();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void OpenGLDLLShutdown()
|
||||
{
|
||||
// there is no way to tell SDL to unload the library
|
||||
if (dlHandle != NULL)
|
||||
{
|
||||
dlclose(dlHandle);
|
||||
dlHandle = NULL;
|
||||
}
|
||||
|
||||
unbindGLFunctions();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
GLState gGLState;
|
||||
|
||||
bool gOpenGLDisablePT = false;
|
||||
bool gOpenGLDisableCVA = false;
|
||||
bool gOpenGLDisableTEC = false;
|
||||
bool gOpenGLDisableARBMT = false;
|
||||
bool gOpenGLDisableFC = false;
|
||||
bool gOpenGLDisableTCompress = false;
|
||||
bool gOpenGLNoEnvColor = false;
|
||||
float gOpenGLGammaCorrection = 0.5;
|
||||
bool gOpenGLNoDrawArraysAlpha = false;
|
||||
|
||||
// JMQTODO: really need a platform-shared version of this nastiness
|
||||
bool GL_EXT_Init( )
|
||||
{
|
||||
// Load extensions...
|
||||
//
|
||||
const char* pExtString = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
|
||||
gGLState.primMode = 0;
|
||||
U32 extBitMask = 0;
|
||||
|
||||
// GL_EXT_paletted_texture
|
||||
if (pExtString && dStrstr(pExtString, (const char*)"GL_EXT_paletted_texture") != NULL)
|
||||
{
|
||||
extBitMask |= EXT_paletted_texture;
|
||||
gGLState.suppPalettedTexture = true;
|
||||
}
|
||||
else
|
||||
gGLState.suppPalettedTexture = false;
|
||||
|
||||
// EXT_compiled_vertex_array
|
||||
if (pExtString && dStrstr(pExtString, (const char*)"GL_EXT_compiled_vertex_array") != NULL)
|
||||
{
|
||||
extBitMask |= EXT_compiled_vertex_array;
|
||||
gGLState.suppLockedArrays = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
gGLState.suppLockedArrays = false;
|
||||
}
|
||||
|
||||
// ARB_multitexture
|
||||
if (pExtString && dStrstr(pExtString, (const char*)"GL_ARB_multitexture") != NULL)
|
||||
{
|
||||
extBitMask |= ARB_multitexture;
|
||||
gGLState.suppARBMultitexture = true;
|
||||
} else {
|
||||
gGLState.suppARBMultitexture = false;
|
||||
}
|
||||
|
||||
// EXT_blend_color
|
||||
if(pExtString && dStrstr(pExtString, (const char*)"GL_EXT_blend_color") != NULL)
|
||||
{
|
||||
extBitMask |= EXT_blend_color;
|
||||
gGLState.suppEXTblendcolor = true;
|
||||
} else {
|
||||
gGLState.suppEXTblendcolor = false;
|
||||
}
|
||||
|
||||
// EXT_blend_minmax
|
||||
if(pExtString && dStrstr(pExtString, (const char*)"GL_EXT_blend_minmax") != NULL)
|
||||
{
|
||||
extBitMask |= EXT_blend_color;
|
||||
gGLState.suppEXTblendminmax = true;
|
||||
} else {
|
||||
gGLState.suppEXTblendminmax = false;
|
||||
}
|
||||
|
||||
// EXT_fog_coord
|
||||
if (pExtString && dStrstr(pExtString, (const char*)"GL_EXT_fog_coord") != NULL)
|
||||
{
|
||||
extBitMask |= EXT_fog_coord;
|
||||
gGLState.suppFogCoord = true;
|
||||
} else {
|
||||
gGLState.suppFogCoord = false;
|
||||
}
|
||||
|
||||
// EXT_texture_compression_s3tc
|
||||
if (pExtString && dStrstr(pExtString, (const char*)"GL_EXT_texture_compression_s3tc") != NULL)
|
||||
gGLState.suppS3TC = true;
|
||||
else
|
||||
gGLState.suppS3TC = false;
|
||||
|
||||
// ARB_texture_compression
|
||||
if (pExtString && dStrstr(pExtString, (const char*)"GL_ARB_texture_compression") != NULL)
|
||||
{
|
||||
extBitMask |= ARB_texture_compression;
|
||||
gGLState.suppTextureCompression = true;
|
||||
} else {
|
||||
gGLState.suppTextureCompression = false;
|
||||
}
|
||||
|
||||
// NV_vertex_array_range (not on *nix)
|
||||
gGLState.suppVertexArrayRange = false;
|
||||
|
||||
// 3DFX_texture_compression_FXT1
|
||||
if (pExtString && dStrstr(pExtString, (const char*)"3DFX_texture_compression_FXT1") != NULL)
|
||||
gGLState.suppFXT1 = true;
|
||||
else
|
||||
gGLState.suppFXT1 = false;
|
||||
|
||||
if (!bindEXTFunctions(extBitMask))
|
||||
Con::warnf("You are missing some OpenGL Extensions. You may experience rendering problems.");
|
||||
|
||||
// Binary states, i.e., no supporting functions
|
||||
// EXT_packed_pixels
|
||||
// EXT_texture_env_combine
|
||||
//
|
||||
// dhc note: a number of these can have multiple matching 'versions', private, ext, and arb.
|
||||
gGLState.suppPackedPixels = pExtString? (dStrstr(pExtString, (const char*)"GL_EXT_packed_pixels") != NULL) : false;
|
||||
gGLState.suppTextureEnvCombine = pExtString? (dStrstr(pExtString, (const char*)"GL_EXT_texture_env_combine") != NULL) : false;
|
||||
gGLState.suppEdgeClamp = pExtString? (dStrstr(pExtString, (const char*)"GL_EXT_texture_edge_clamp") != NULL) : false;
|
||||
gGLState.suppEdgeClamp |= pExtString? (dStrstr(pExtString, (const char*)"GL_SGIS_texture_edge_clamp") != NULL) : false;
|
||||
gGLState.suppTexEnvAdd = pExtString? (dStrstr(pExtString, (const char*)"GL_ARB_texture_env_add") != NULL) : false;
|
||||
gGLState.suppTexEnvAdd |= pExtString? (dStrstr(pExtString, (const char*)"GL_EXT_texture_env_add") != NULL) : false;
|
||||
|
||||
// Anisotropic filtering
|
||||
gGLState.suppTexAnisotropic = pExtString? (dStrstr(pExtString, (const char*)"GL_EXT_texture_filter_anisotropic") != NULL) : false;
|
||||
if (gGLState.suppTexAnisotropic)
|
||||
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &gGLState.maxAnisotropy);
|
||||
if (gGLState.suppARBMultitexture)
|
||||
glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &gGLState.maxTextureUnits);
|
||||
else
|
||||
gGLState.maxTextureUnits = 1;
|
||||
|
||||
// JMQ: vsync/swap interval skipped
|
||||
gGLState.suppSwapInterval = false;
|
||||
|
||||
Con::printf("OpenGL Init: Enabled Extensions");
|
||||
if (gGLState.suppARBMultitexture) Con::printf(" ARB_multitexture (Max Texture Units: %d)", gGLState.maxTextureUnits);
|
||||
if (gGLState.suppEXTblendcolor) Con::printf(" EXT_blend_color");
|
||||
if (gGLState.suppEXTblendminmax) Con::printf(" EXT_blend_minmax");
|
||||
if (gGLState.suppPalettedTexture) Con::printf(" EXT_paletted_texture");
|
||||
if (gGLState.suppLockedArrays) Con::printf(" EXT_compiled_vertex_array");
|
||||
if (gGLState.suppVertexArrayRange) Con::printf(" NV_vertex_array_range");
|
||||
if (gGLState.suppTextureEnvCombine) Con::printf(" EXT_texture_env_combine");
|
||||
if (gGLState.suppPackedPixels) Con::printf(" EXT_packed_pixels");
|
||||
if (gGLState.suppFogCoord) Con::printf(" EXT_fog_coord");
|
||||
if (gGLState.suppTextureCompression) Con::printf(" ARB_texture_compression");
|
||||
if (gGLState.suppS3TC) Con::printf(" EXT_texture_compression_s3tc");
|
||||
if (gGLState.suppFXT1) Con::printf(" 3DFX_texture_compression_FXT1");
|
||||
if (gGLState.suppTexEnvAdd) Con::printf(" (ARB|EXT)_texture_env_add");
|
||||
if (gGLState.suppTexAnisotropic) Con::printf(" EXT_texture_filter_anisotropic (Max anisotropy: %f)", gGLState.maxAnisotropy);
|
||||
if (gGLState.suppSwapInterval) Con::printf(" WGL_EXT_swap_control");
|
||||
|
||||
Con::warnf("OpenGL Init: Disabled Extensions");
|
||||
if (!gGLState.suppARBMultitexture) Con::warnf(" ARB_multitexture");
|
||||
if (!gGLState.suppEXTblendcolor) Con::warnf(" EXT_blend_color");
|
||||
if (!gGLState.suppEXTblendminmax) Con::warnf(" EXT_blend_minmax");
|
||||
if (!gGLState.suppPalettedTexture) Con::warnf(" EXT_paletted_texture");
|
||||
if (!gGLState.suppLockedArrays) Con::warnf(" EXT_compiled_vertex_array");
|
||||
if (!gGLState.suppVertexArrayRange) Con::warnf(" NV_vertex_array_range");
|
||||
if (!gGLState.suppTextureEnvCombine) Con::warnf(" EXT_texture_env_combine");
|
||||
if (!gGLState.suppPackedPixels) Con::warnf(" EXT_packed_pixels");
|
||||
if (!gGLState.suppFogCoord) Con::warnf(" EXT_fog_coord");
|
||||
if (!gGLState.suppTextureCompression) Con::warnf(" ARB_texture_compression");
|
||||
if (!gGLState.suppS3TC) Con::warnf(" EXT_texture_compression_s3tc");
|
||||
if (!gGLState.suppFXT1) Con::warnf(" 3DFX_texture_compression_FXT1");
|
||||
if (!gGLState.suppTexEnvAdd) Con::warnf(" (ARB|EXT)_texture_env_add");
|
||||
if (!gGLState.suppTexAnisotropic) Con::warnf(" EXT_texture_filter_anisotropic");
|
||||
if (!gGLState.suppSwapInterval) Con::warnf(" WGL_EXT_swap_control");
|
||||
Con::printf(" ");
|
||||
|
||||
// Set some console variables:
|
||||
Con::setBoolVariable( "$FogCoordSupported", gGLState.suppFogCoord );
|
||||
Con::setBoolVariable( "$TextureCompressionSupported", gGLState.suppTextureCompression );
|
||||
Con::setBoolVariable( "$AnisotropySupported", gGLState.suppTexAnisotropic );
|
||||
Con::setBoolVariable( "$PalettedTextureSupported", gGLState.suppPalettedTexture );
|
||||
Con::setBoolVariable( "$SwapIntervalSupported", gGLState.suppSwapInterval );
|
||||
|
||||
if (!gGLState.suppPalettedTexture && Con::getBoolVariable("$pref::OpenGL::forcePalettedTexture",false))
|
||||
{
|
||||
Con::setBoolVariable("$pref::OpenGL::forcePalettedTexture", false);
|
||||
Con::setBoolVariable("$pref::OpenGL::force16BitTexture", true);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
36
engine/platformX86UNIX/x86UNIXIO.cc
Executable file
36
engine/platformX86UNIX/x86UNIXIO.cc
Executable file
@ -0,0 +1,36 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
#include "platformX86UNIX/platformX86UNIX.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <libgen.h>
|
||||
#include <dirent.h>
|
||||
|
||||
int x86UNIXOpen(const char *path, int oflag)
|
||||
{
|
||||
return open(path, oflag, 0666);
|
||||
}
|
||||
|
||||
int x86UNIXClose(int fd)
|
||||
{
|
||||
return close(fd);
|
||||
}
|
||||
|
||||
ssize_t x86UNIXRead(int fd, void *buf, size_t nbytes)
|
||||
{
|
||||
return read(fd, buf, nbytes);
|
||||
}
|
||||
|
||||
ssize_t x86UNIXWrite(int fd, const void *buf, size_t nbytes)
|
||||
{
|
||||
return write(fd, buf, nbytes);
|
||||
}
|
589
engine/platformX86UNIX/x86UNIXInput.cc
Executable file
589
engine/platformX86UNIX/x86UNIXInput.cc
Executable file
@ -0,0 +1,589 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
#include "platformX86UNIX/platformX86UNIX.h"
|
||||
#include "platform/platformInput.h"
|
||||
#include "platform/platformVideo.h"
|
||||
#include "platform/event.h"
|
||||
#include "platform/gameInterface.h"
|
||||
#include "console/console.h"
|
||||
#include "platformX86UNIX/x86UNIXState.h"
|
||||
#include "platformX86UNIX/x86UNIXInputManager.h"
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include <X11/keysym.h>
|
||||
|
||||
#include <SDL/SDL.h>
|
||||
|
||||
#ifdef LOG_INPUT
|
||||
#include <time.h>
|
||||
#include <stdarg.h>
|
||||
#include <fcntl.h>
|
||||
#include <platformX86UNIX/x86UNIXUtils.h>
|
||||
|
||||
extern int x86UNIXOpen(const char *path, int oflag);
|
||||
extern int x86UNIXClose(int fd);
|
||||
extern ssize_t x86UNIXWrite(int fd, const void *buf, size_t nbytes);
|
||||
#endif
|
||||
|
||||
class XClipboard
|
||||
{
|
||||
private:
|
||||
Atom mClipboardProperty;
|
||||
Atom mClipboard;
|
||||
Atom mPrimary;
|
||||
bool mInitialized;
|
||||
U8 *mXData;
|
||||
char *mTData;
|
||||
S32 mTDataSize;
|
||||
|
||||
void init();
|
||||
void freeXData();
|
||||
void freeTData();
|
||||
void checkTDataSize(S32 requestedSize);
|
||||
public:
|
||||
XClipboard();
|
||||
~XClipboard();
|
||||
|
||||
bool setClipboard(const char *text);
|
||||
const char* getClipboard();
|
||||
void handleSelectionRequest(XSelectionRequestEvent& request);
|
||||
};
|
||||
|
||||
// Static class variables:
|
||||
InputManager* Input::smManager;
|
||||
|
||||
// smActive is not maintained under unix. Use Input::isActive()
|
||||
// instead
|
||||
bool Input::smActive = false;
|
||||
|
||||
// unix platform state
|
||||
extern x86UNIXPlatformState * x86UNIXState;
|
||||
|
||||
extern AsciiData AsciiTable[NUM_KEYS];
|
||||
|
||||
static XClipboard xclipboard;
|
||||
|
||||
#ifdef LOG_INPUT
|
||||
S32 gInputLog = -1;
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void Input::init()
|
||||
{
|
||||
Con::printf( "Input Init:" );
|
||||
|
||||
destroy();
|
||||
|
||||
#ifdef LOG_INPUT
|
||||
struct tm* newTime;
|
||||
time_t aclock;
|
||||
time( &aclock );
|
||||
newTime = localtime( &aclock );
|
||||
asctime( newTime );
|
||||
|
||||
gInputLog = x86UNIXOpen("input.log", O_WRONLY | O_CREAT);
|
||||
log("Input log opened at %s\n", asctime( newTime ) );
|
||||
log("Operating System:\n" );
|
||||
log(" %s", UUtils->getOSName());
|
||||
log("\n");
|
||||
#endif
|
||||
|
||||
smActive = false;
|
||||
smManager = NULL;
|
||||
|
||||
UInputManager *uInputManager = new UInputManager;
|
||||
if ( !uInputManager->enable() )
|
||||
{
|
||||
Con::errorf( " Failed to enable Input Manager." );
|
||||
delete uInputManager;
|
||||
return;
|
||||
}
|
||||
|
||||
uInputManager->init();
|
||||
|
||||
smManager = uInputManager;
|
||||
|
||||
Con::printf(" Input initialized");
|
||||
Con::printf(" ");
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
ConsoleFunction( isJoystickDetected, bool, 1, 1, "isJoystickDetected()" )
|
||||
{
|
||||
argc; argv;
|
||||
UInputManager* manager = dynamic_cast<UInputManager*>(Input::getManager());
|
||||
if (manager)
|
||||
return manager->joystickDetected();
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
ConsoleFunction( getJoystickAxes, const char*, 2, 2, "getJoystickAxes( instance )" )
|
||||
{
|
||||
argc; argv;
|
||||
UInputManager* manager = dynamic_cast<UInputManager*>(Input::getManager());
|
||||
if (manager)
|
||||
return manager->getJoystickAxesString(dAtoi(argv[1]));
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
U16 Input::getKeyCode( U16 asciiCode )
|
||||
{
|
||||
U16 keyCode = 0;
|
||||
U16 i;
|
||||
|
||||
// This is done three times so the lowerkey will always
|
||||
// be found first. Some foreign keyboards have duplicate
|
||||
// chars on some keys.
|
||||
for ( i = KEY_FIRST; i < NUM_KEYS && !keyCode; i++ )
|
||||
{
|
||||
if ( AsciiTable[i].lower.ascii == asciiCode )
|
||||
{
|
||||
keyCode = i;
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
for ( i = KEY_FIRST; i < NUM_KEYS && !keyCode; i++ )
|
||||
{
|
||||
if ( AsciiTable[i].upper.ascii == asciiCode )
|
||||
{
|
||||
keyCode = i;
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
for ( i = KEY_FIRST; i < NUM_KEYS && !keyCode; i++ )
|
||||
{
|
||||
if ( AsciiTable[i].goofy.ascii == asciiCode )
|
||||
{
|
||||
keyCode = i;
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
return( keyCode );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// This function gets the standard ASCII code corresponding to our key code
|
||||
// and the existing modifier key state.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
U16 Input::getAscii( U16 keyCode, KEY_STATE keyState )
|
||||
{
|
||||
if ( keyCode >= NUM_KEYS )
|
||||
return 0;
|
||||
|
||||
switch ( keyState )
|
||||
{
|
||||
case STATE_LOWER:
|
||||
return AsciiTable[keyCode].lower.ascii;
|
||||
case STATE_UPPER:
|
||||
return AsciiTable[keyCode].upper.ascii;
|
||||
case STATE_GOOFY:
|
||||
return AsciiTable[keyCode].goofy.ascii;
|
||||
default:
|
||||
return(0);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void Input::destroy()
|
||||
{
|
||||
#ifdef LOG_INPUT
|
||||
if ( gInputLog != -1 )
|
||||
{
|
||||
log( "*** CLOSING LOG ***\n" );
|
||||
x86UNIXClose(gInputLog);
|
||||
gInputLog = -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( smManager && smManager->isEnabled() )
|
||||
{
|
||||
smManager->disable();
|
||||
delete smManager;
|
||||
smManager = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool Input::enable()
|
||||
{
|
||||
if ( smManager && !smManager->isEnabled() )
|
||||
return( smManager->enable() );
|
||||
|
||||
return( false );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void Input::disable()
|
||||
{
|
||||
if ( smManager && smManager->isEnabled() )
|
||||
smManager->disable();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void Input::activate()
|
||||
{
|
||||
if ( smManager && smManager->isEnabled() && !isActive())
|
||||
{
|
||||
#ifdef LOG_INPUT
|
||||
Input::log( "Activating Input...\n" );
|
||||
#endif
|
||||
UInputManager* uInputManager = dynamic_cast<UInputManager*>( smManager );
|
||||
if ( uInputManager )
|
||||
uInputManager->activate();
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void Input::deactivate()
|
||||
{
|
||||
if ( smManager && smManager->isEnabled() && isActive() )
|
||||
{
|
||||
#ifdef LOG_INPUT
|
||||
Input::log( "Deactivating Input...\n" );
|
||||
#endif
|
||||
UInputManager* uInputManager = dynamic_cast<UInputManager*>( smManager );
|
||||
if ( uInputManager )
|
||||
uInputManager->deactivate();
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void Input::reactivate()
|
||||
{
|
||||
Input::deactivate();
|
||||
Input::activate();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool Input::isEnabled()
|
||||
{
|
||||
if ( smManager )
|
||||
return smManager->isEnabled();
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool Input::isActive()
|
||||
{
|
||||
UInputManager* uInputManager = dynamic_cast<UInputManager*>( smManager );
|
||||
if ( uInputManager )
|
||||
return uInputManager->isActive();
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void Input::process()
|
||||
{
|
||||
if ( smManager )
|
||||
smManager->process();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
InputManager* Input::getManager()
|
||||
{
|
||||
return smManager;
|
||||
}
|
||||
|
||||
#ifdef LOG_INPUT
|
||||
//------------------------------------------------------------------------------
|
||||
void Input::log( const char* format, ... )
|
||||
{
|
||||
if ( gInputLog == -1)
|
||||
return;
|
||||
|
||||
va_list argptr;
|
||||
va_start( argptr, format );
|
||||
|
||||
const int BufSize = 4096;
|
||||
char buffer[BufSize];
|
||||
dVsprintf( buffer, BufSize, format, argptr );
|
||||
x86UNIXWrite(gInputLog, buffer, dStrlen( buffer ));
|
||||
va_end( argptr );
|
||||
}
|
||||
|
||||
ConsoleFunction( inputLog, void, 2, 2, "inputLog( string )" )
|
||||
{
|
||||
argc;
|
||||
Input::log( "%s\n", argv[1] );
|
||||
}
|
||||
#endif // LOG_INPUT
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void NotifySelectionEvent(XEvent& event)
|
||||
{
|
||||
// somebody sent us a select event
|
||||
if (event.type == SelectionRequest)
|
||||
xclipboard.handleSelectionRequest(event.xselectionrequest);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
const char* Platform::getClipboard()
|
||||
{
|
||||
return xclipboard.getClipboard();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool Platform::setClipboard(const char *text)
|
||||
{
|
||||
return xclipboard.setClipboard(text);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// XClipboard members
|
||||
XClipboard::XClipboard()
|
||||
{
|
||||
mInitialized = false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
XClipboard::~XClipboard()
|
||||
{
|
||||
freeXData();
|
||||
freeTData();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void XClipboard::init()
|
||||
{
|
||||
DisplayPtrManager xdisplay;
|
||||
Display* display = xdisplay.getDisplayPointer();
|
||||
|
||||
mClipboardProperty = XInternAtom(display,
|
||||
"TORQUE_CLIPBOARD_ATOM", False);
|
||||
mClipboard = XInternAtom(display, "CLIPBOARD",
|
||||
False);
|
||||
mPrimary = XA_PRIMARY; //XInternAtom(display, "PRIMARY", False);
|
||||
mXData = NULL;
|
||||
mTData = NULL;
|
||||
mTDataSize = 0;
|
||||
|
||||
mInitialized = true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
inline void XClipboard::freeXData()
|
||||
{
|
||||
if (mXData != NULL)
|
||||
{
|
||||
XFree(mXData);
|
||||
mXData = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
inline void XClipboard::freeTData()
|
||||
{
|
||||
if (mTData != NULL)
|
||||
{
|
||||
dRealFree(mTData);
|
||||
mTData = NULL;
|
||||
mTDataSize = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// JMQ: As you might expect, X clipboard usage is bizarre. I
|
||||
// found this document to be useful.
|
||||
//
|
||||
// http://www.freedesktop.org/standards/clipboards.txt
|
||||
//
|
||||
// JMQ: later note: programming the X clipboard is not just
|
||||
// bizarre, it SUCKS. No wonder so many apps have
|
||||
// clipboard problems.
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
const char* XClipboard::getClipboard()
|
||||
{
|
||||
DisplayPtrManager xdisplay;
|
||||
Display* display = xdisplay.getDisplayPointer();
|
||||
|
||||
if (!mInitialized)
|
||||
init();
|
||||
|
||||
// find the owner of the clipboard
|
||||
Atom targetSelection = mClipboard;
|
||||
Window clipOwner = XGetSelectionOwner(display,
|
||||
targetSelection);
|
||||
if (clipOwner == None)
|
||||
{
|
||||
// It seems like KDE/QT reads the clipboard but doesn't set it.
|
||||
// This is a bug, that supposedly will be fixed in QT3.
|
||||
// I tried working around this by using
|
||||
// PRIMARY instead of CLIPBOARD, but this has some nonintuitive
|
||||
// side effects. So, no pasting from KDE apps for now.
|
||||
//targetSelection = mPrimary;
|
||||
//clipOwner = XGetSelectionOwner(display, targetSelection);
|
||||
}
|
||||
|
||||
if (clipOwner == None)
|
||||
// oh well
|
||||
return "";
|
||||
|
||||
// request that the owner convert the selection to a string
|
||||
XConvertSelection(display, targetSelection,
|
||||
XA_STRING, mClipboardProperty, x86UNIXState->getWindow(), CurrentTime);
|
||||
|
||||
// flush the output buffer to make sure the selection request event gets
|
||||
// sent now
|
||||
XFlush(display);
|
||||
|
||||
XEvent xevent;
|
||||
|
||||
// if our window is the current owner, (e.g. copy from one part of
|
||||
// torque and paste to another), then we just sent an event to our
|
||||
// window that won't get processed until we get back to the event
|
||||
// loop in x86Unixwindow. So look for selection request events in
|
||||
// the event queue immediately and handle them.
|
||||
while (XCheckTypedWindowEvent(display,
|
||||
x86UNIXState->getWindow(), SelectionRequest, &xevent))
|
||||
handleSelectionRequest(xevent.xselectionrequest);
|
||||
|
||||
// poll for the SelectionNotify event for 5 seconds. in most cases
|
||||
// we should get the event very quickly
|
||||
U32 startTime = Platform::getRealMilliseconds();
|
||||
bool timeOut = false;
|
||||
while (!XCheckTypedWindowEvent(display,
|
||||
x86UNIXState->getWindow(), SelectionNotify, &xevent) &&
|
||||
!timeOut)
|
||||
{
|
||||
// we'll be spinning here, but who cares
|
||||
if ((Platform::getRealMilliseconds() - startTime) > 5000)
|
||||
timeOut = true;
|
||||
}
|
||||
|
||||
if (timeOut)
|
||||
{
|
||||
Con::warnf(ConsoleLogEntry::General,
|
||||
"XClipboard: waited too long for owner to convert selection");
|
||||
return "";
|
||||
}
|
||||
|
||||
if (xevent.xselection.property == None)
|
||||
return "";
|
||||
|
||||
// free the X data from a previous get
|
||||
freeXData();
|
||||
|
||||
// grab the string data from the property
|
||||
Atom actual_type;
|
||||
int actual_format;
|
||||
unsigned long bytes_after;
|
||||
unsigned long nitems;
|
||||
// query the property length the 250000 is "the length in 32-bit
|
||||
// multiples of the data to be retrieved". so we support up to a
|
||||
// million bytes of returned data.
|
||||
int numToRetrieve = 250000;
|
||||
int status = XGetWindowProperty(display,
|
||||
x86UNIXState->getWindow(),
|
||||
mClipboardProperty, 0, numToRetrieve, True, XA_STRING,
|
||||
&actual_type, &actual_format, &nitems, &bytes_after, &mXData);
|
||||
|
||||
// we should have returned OK, with string type, 8bit data,
|
||||
// and > 0 items.
|
||||
if ((status != Success) || (actual_type != XA_STRING) ||
|
||||
(actual_format != 8) || (nitems == 0))
|
||||
return "";
|
||||
|
||||
// if there is data left in the clipboard, warn about it
|
||||
if (bytes_after > 0)
|
||||
Con::warnf(ConsoleLogEntry::General,
|
||||
"XClipboard: some data was not retrieved");
|
||||
|
||||
return reinterpret_cast<const char *>(mXData);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void XClipboard::checkTDataSize(S32 requestedSize)
|
||||
{
|
||||
if (mTDataSize < requestedSize)
|
||||
{
|
||||
freeTData();
|
||||
mTData = static_cast<char*>(dRealMalloc(sizeof(char) * requestedSize));
|
||||
AssertFatal(mTData, "unable to allocate clipboard buffer data!");
|
||||
mTDataSize = requestedSize;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool XClipboard::setClipboard(const char *text)
|
||||
{
|
||||
DisplayPtrManager xdisplay;
|
||||
Display* display = xdisplay.getDisplayPointer();
|
||||
|
||||
if (!mInitialized)
|
||||
init();
|
||||
|
||||
// get the length of the text
|
||||
S32 len = dStrlen(text) + 1;
|
||||
|
||||
// reallocate the storage buffer if necessary
|
||||
checkTDataSize(len);
|
||||
|
||||
// copy the data into the storage buffer
|
||||
dStrcpy(mTData, text);
|
||||
|
||||
// tell X that we own the clipboard. (we'll get events
|
||||
// if an app tries to paste)
|
||||
XSetSelectionOwner(display, mClipboard,
|
||||
x86UNIXState->getWindow(), CurrentTime);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void XClipboard::handleSelectionRequest(XSelectionRequestEvent& request)
|
||||
{
|
||||
DisplayPtrManager xdisplay;
|
||||
Display* display = xdisplay.getDisplayPointer();
|
||||
|
||||
// init our response
|
||||
XSelectionEvent notify;
|
||||
|
||||
notify.type = SelectionNotify;
|
||||
notify.display = display;
|
||||
notify.requestor = request.requestor;
|
||||
notify.selection = request.selection;
|
||||
notify.target = XA_STRING;
|
||||
notify.property = None;
|
||||
notify.time = CurrentTime;
|
||||
|
||||
// make sure the owner is our window, and that the
|
||||
// requestor wants the clipboard
|
||||
if (request.owner == x86UNIXState->getWindow() &&
|
||||
request.selection == mClipboard)
|
||||
{
|
||||
notify.property = request.property;
|
||||
// check to see if they did not set the property
|
||||
if (notify.property == None)
|
||||
notify.property = mClipboardProperty;
|
||||
|
||||
// get the length of the data in the clipboard
|
||||
S32 length = dStrlen(mTData);
|
||||
// set the property on the requestor window
|
||||
XChangeProperty(display, request.requestor,
|
||||
notify.property, XA_STRING,
|
||||
8, PropModeReplace, reinterpret_cast<const unsigned char*>(mTData),
|
||||
length);
|
||||
}
|
||||
XSendEvent(display, notify.requestor, False, 0,
|
||||
reinterpret_cast<XEvent*>(¬ify));
|
||||
|
||||
// flush the output buffer to send the event now
|
||||
XFlush(display);
|
||||
}
|
1820
engine/platformX86UNIX/x86UNIXInputManager.cc
Executable file
1820
engine/platformX86UNIX/x86UNIXInputManager.cc
Executable file
File diff suppressed because it is too large
Load Diff
175
engine/platformX86UNIX/x86UNIXInputManager.h
Executable file
175
engine/platformX86UNIX/x86UNIXInputManager.h
Executable file
@ -0,0 +1,175 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
#ifndef _X86UNIXINPUTMANAGER_H_
|
||||
#define _X86UNIXINPUTMANAGER_H_
|
||||
|
||||
#include "core/tVector.h"
|
||||
#include "platform/platformInput.h"
|
||||
#include "platformX86UNIX/platformX86UNIX.h"
|
||||
|
||||
#include <SDL/SDL_events.h>
|
||||
|
||||
#define NUM_KEYS ( KEY_OEM_102 + 1 )
|
||||
#define KEY_FIRST KEY_ESCAPE
|
||||
|
||||
struct AsciiData
|
||||
{
|
||||
struct KeyData
|
||||
{
|
||||
U16 ascii;
|
||||
bool isDeadChar;
|
||||
};
|
||||
|
||||
KeyData upper;
|
||||
KeyData lower;
|
||||
KeyData goofy;
|
||||
};
|
||||
|
||||
typedef struct _SDL_Joystick;
|
||||
|
||||
struct JoystickAxisInfo
|
||||
{
|
||||
S32 type;
|
||||
S32 minValue;
|
||||
S32 maxValue;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
class JoystickInputDevice : public InputDevice
|
||||
{
|
||||
public:
|
||||
JoystickInputDevice(U8 deviceID);
|
||||
~JoystickInputDevice();
|
||||
|
||||
bool activate();
|
||||
bool deactivate();
|
||||
bool isActive() { return( mActive ); }
|
||||
|
||||
U8 getDeviceType() { return( JoystickDeviceType ); }
|
||||
U8 getDeviceID() { return( mDeviceID ); }
|
||||
const char* getName();
|
||||
const char* getJoystickAxesString();
|
||||
|
||||
void loadJoystickInfo();
|
||||
void loadAxisInfo();
|
||||
JoystickAxisInfo& getAxisInfo(int axisNum) { return mAxisList[axisNum]; }
|
||||
|
||||
bool process();
|
||||
void reset();
|
||||
|
||||
private:
|
||||
bool mActive;
|
||||
U8 mDeviceID;
|
||||
SDL_Joystick* mStick;
|
||||
Vector<JoystickAxisInfo> mAxisList;
|
||||
Vector<bool> mButtonState;
|
||||
Vector<U8> mHatState;
|
||||
|
||||
S32 mNumAxes;
|
||||
S32 mNumButtons;
|
||||
S32 mNumHats;
|
||||
S32 mNumBalls;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
class UInputManager : public InputManager
|
||||
{
|
||||
friend bool JoystickInputDevice::process(); // for joystick event funcs
|
||||
friend void JoystickInputDevice::reset();
|
||||
|
||||
public:
|
||||
UInputManager();
|
||||
|
||||
void init();
|
||||
bool enable();
|
||||
void disable();
|
||||
void activate();
|
||||
void deactivate();
|
||||
void setWindowLocked(bool locked);
|
||||
bool isActive() { return( mActive ); }
|
||||
|
||||
void onDeleteNotify( SimObject* object );
|
||||
bool onAdd();
|
||||
void onRemove();
|
||||
|
||||
void process();
|
||||
|
||||
bool enableKeyboard();
|
||||
void disableKeyboard();
|
||||
bool isKeyboardEnabled() { return( mKeyboardEnabled ); }
|
||||
bool activateKeyboard();
|
||||
void deactivateKeyboard();
|
||||
bool isKeyboardActive() { return( mKeyboardActive ); }
|
||||
|
||||
bool enableMouse();
|
||||
void disableMouse();
|
||||
bool isMouseEnabled() { return( mMouseEnabled ); }
|
||||
bool activateMouse();
|
||||
void deactivateMouse();
|
||||
bool isMouseActive() { return( mMouseActive ); }
|
||||
|
||||
bool enableJoystick();
|
||||
void disableJoystick();
|
||||
bool isJoystickEnabled() { return( mJoystickEnabled ); }
|
||||
bool activateJoystick();
|
||||
void deactivateJoystick();
|
||||
bool isJoystickActive() { return( mJoystickActive ); }
|
||||
|
||||
void setLocking(bool enabled);
|
||||
bool getLocking() { return mLocking; }
|
||||
|
||||
const char* getJoystickAxesString( U32 deviceID );
|
||||
bool joystickDetected() { return mJoystickList.size() > 0; }
|
||||
private:
|
||||
typedef SimGroup Parent;
|
||||
// the following vector is just for quick access during event processing.
|
||||
// it does not manage the cleanup of the JoystickInputDevice objects
|
||||
Vector<JoystickInputDevice*> mJoystickList;
|
||||
|
||||
bool mKeyboardEnabled;
|
||||
bool mMouseEnabled;
|
||||
bool mJoystickEnabled;
|
||||
|
||||
bool mKeyboardActive;
|
||||
bool mMouseActive;
|
||||
bool mJoystickActive;
|
||||
|
||||
bool mActive;
|
||||
|
||||
// Device state variables
|
||||
S32 mModifierKeys;
|
||||
bool mKeyboardState[256];
|
||||
bool mMouseButtonState[3];
|
||||
|
||||
// last mousex and y are maintained when window is unlocked
|
||||
S32 mLastMouseX;
|
||||
S32 mLastMouseY;
|
||||
|
||||
void initJoystick();
|
||||
|
||||
void resetKeyboardState();
|
||||
void resetMouseState();
|
||||
void resetInputState();
|
||||
|
||||
void lockInput();
|
||||
void unlockInput();
|
||||
bool mLocking;
|
||||
|
||||
void joyHatEvent(U8 deviceID, U8 hatNum,
|
||||
U8 prevHatState, U8 currHatState);
|
||||
void joyButtonEvent(U8 deviceID, U8 buttonNum, bool pressed);
|
||||
void joyButtonEvent(const SDL_Event& event);
|
||||
void joyAxisEvent(const SDL_Event& event);
|
||||
void joyAxisEvent(U8 deviceID, U8 axisNum, S16 axisValue);
|
||||
void mouseButtonEvent(const SDL_Event& event);
|
||||
void mouseMotionEvent(const SDL_Event& event);
|
||||
void keyEvent(const SDL_Event& event);
|
||||
bool processKeyEvent(InputEvent &event);
|
||||
};
|
||||
|
||||
#endif // _H_X86UNIXINPUTMANAGER_
|
107
engine/platformX86UNIX/x86UNIXMath.cc
Executable file
107
engine/platformX86UNIX/x86UNIXMath.cc
Executable file
@ -0,0 +1,107 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "console/console.h"
|
||||
#include "math/mMath.h"
|
||||
|
||||
|
||||
extern void mInstallLibrary_C();
|
||||
extern void mInstallLibrary_ASM();
|
||||
|
||||
|
||||
extern void mInstall_AMD_Math();
|
||||
extern void mInstall_Library_SSE();
|
||||
|
||||
|
||||
//--------------------------------------
|
||||
ConsoleFunction( MathInit, void, 1, 10, "(detect|C|FPU|MMX|3DNOW|SSE|...)")
|
||||
{
|
||||
U32 properties = CPU_PROP_C; // C entensions are always used
|
||||
|
||||
if (argc == 1)
|
||||
{
|
||||
Math::init(0);
|
||||
return;
|
||||
}
|
||||
for (argc--, argv++; argc; argc--, argv++)
|
||||
{
|
||||
if (dStricmp(*argv, "DETECT") == 0) {
|
||||
Math::init(0);
|
||||
return;
|
||||
}
|
||||
if (dStricmp(*argv, "C") == 0) {
|
||||
properties |= CPU_PROP_C;
|
||||
continue;
|
||||
}
|
||||
if (dStricmp(*argv, "FPU") == 0) {
|
||||
properties |= CPU_PROP_FPU;
|
||||
continue;
|
||||
}
|
||||
if (dStricmp(*argv, "MMX") == 0) {
|
||||
properties |= CPU_PROP_MMX;
|
||||
continue;
|
||||
}
|
||||
if (dStricmp(*argv, "3DNOW") == 0) {
|
||||
properties |= CPU_PROP_3DNOW;
|
||||
continue;
|
||||
}
|
||||
if (dStricmp(*argv, "SSE") == 0) {
|
||||
properties |= CPU_PROP_SSE;
|
||||
continue;
|
||||
}
|
||||
Con::printf("Error: MathInit(): ignoring unknown math extension '%s'", *argv);
|
||||
}
|
||||
Math::init(properties);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void Math::init(U32 properties)
|
||||
{
|
||||
if (!properties)
|
||||
// detect what's available
|
||||
properties = Platform::SystemInfo.processor.properties;
|
||||
else
|
||||
// Make sure we're not asking for anything that's not supported
|
||||
properties &= Platform::SystemInfo.processor.properties;
|
||||
|
||||
Con::printf("Math Init:");
|
||||
Con::printf(" Installing Standard C extensions");
|
||||
mInstallLibrary_C();
|
||||
|
||||
Con::printf(" Installing Assembly extensions");
|
||||
mInstallLibrary_ASM();
|
||||
|
||||
if (properties & CPU_PROP_FPU)
|
||||
{
|
||||
Con::printf(" Installing FPU extensions");
|
||||
}
|
||||
|
||||
if (properties & CPU_PROP_MMX)
|
||||
{
|
||||
Con::printf(" Installing MMX extensions");
|
||||
if (properties & CPU_PROP_3DNOW)
|
||||
{
|
||||
Con::printf(" Installing 3DNow extensions");
|
||||
mInstall_AMD_Math();
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(__MWERKS__) || (__MWERKS__ >= 0x2400)
|
||||
if (properties & CPU_PROP_SSE)
|
||||
{
|
||||
Con::printf(" Installing SSE extensions");
|
||||
mInstall_Library_SSE();
|
||||
}
|
||||
#endif //mwerks>2.4
|
||||
|
||||
Con::printf(" ");
|
||||
}
|
||||
|
||||
|
38
engine/platformX86UNIX/x86UNIXMath_ASM.cc
Executable file
38
engine/platformX86UNIX/x86UNIXMath_ASM.cc
Executable file
@ -0,0 +1,38 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "math/mMath.h"
|
||||
|
||||
static S32 m_mulDivS32_ASM(S32 a, S32 b, S32 c)
|
||||
{ // a * b / c
|
||||
S32 r;
|
||||
|
||||
__asm__ __volatile__(
|
||||
"imul %2\n"
|
||||
"idiv %3\n"
|
||||
: "=a" (r) : "a" (a) , "b" (b) , "c" (c)
|
||||
);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
static U32 m_mulDivU32_ASM(S32 a, S32 b, U32 c)
|
||||
{ // a * b / c
|
||||
S32 r;
|
||||
__asm__ __volatile__(
|
||||
"mov $0, %%edx\n"
|
||||
"mul %2\n"
|
||||
"div %3\n"
|
||||
: "=a" (r) : "a" (a) , "b" (b) , "c" (c)
|
||||
);
|
||||
return r;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void mInstallLibrary_ASM()
|
||||
{
|
||||
m_mulDivS32 = m_mulDivS32_ASM;
|
||||
m_mulDivU32 = m_mulDivU32_ASM;
|
||||
}
|
54
engine/platformX86UNIX/x86UNIXMemory.cc
Executable file
54
engine/platformX86UNIX/x86UNIXMemory.cc
Executable file
@ -0,0 +1,54 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
#include "platformX86UNIX/platformX86UNIX.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
void* dMemcpy(void *dst, const void *src, unsigned size)
|
||||
{
|
||||
return memcpy(dst,src,size);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------
|
||||
void* dMemmove(void *dst, const void *src, unsigned size)
|
||||
{
|
||||
return memmove(dst,src,size);
|
||||
}
|
||||
|
||||
//--------------------------------------
|
||||
void* dMemset(void *dst, S32 c, unsigned size)
|
||||
{
|
||||
return memset(dst,c,size);
|
||||
}
|
||||
|
||||
//--------------------------------------
|
||||
S32 dMemcmp(const void *ptr1, const void *ptr2, unsigned len)
|
||||
{
|
||||
return memcmp(ptr1, ptr2, len);
|
||||
}
|
||||
|
||||
#ifdef new
|
||||
#undef new
|
||||
#endif
|
||||
|
||||
//--------------------------------------
|
||||
void* FN_CDECL operator new(dsize_t, void* ptr)
|
||||
{
|
||||
return (ptr);
|
||||
}
|
||||
|
||||
void* dRealMalloc(dsize_t s)
|
||||
{
|
||||
return malloc(s);
|
||||
}
|
||||
|
||||
void dRealFree(void* p)
|
||||
{
|
||||
free(p);
|
||||
}
|
||||
|
480
engine/platformX86UNIX/x86UNIXMessageBox.cc
Executable file
480
engine/platformX86UNIX/x86UNIXMessageBox.cc
Executable file
@ -0,0 +1,480 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/Xatom.h>
|
||||
|
||||
#include "platformX86UNIX/x86UNIXMessageBox.h"
|
||||
|
||||
#define MessageBox_MaxWinWidth 800
|
||||
#define MessageBox_MaxWinHeight 600
|
||||
#define MessageBox_MinWinWidth 450
|
||||
|
||||
#define MessageBox_ButtonBoxWidth 60
|
||||
#define MessageBox_ButtonBoxHeight 22
|
||||
#define MessageBox_ButtonSpacer 20
|
||||
#define MessageBox_ButtonVMargin 10
|
||||
#define MessageBox_ButtonHMargin 10
|
||||
|
||||
#define MessageBox_LineSpacer 2
|
||||
#define MessageBox_LineVMargin 10
|
||||
#define MessageBox_LineHMargin 10
|
||||
|
||||
XMessageBoxButton::XMessageBoxButton()
|
||||
{
|
||||
strcpy(mLabel, "");
|
||||
mClickVal = -1;
|
||||
mLabelWidth = mX = mY = mWidth = mHeight = mMouseX = mMouseX = -1;
|
||||
mMouseDown = false;
|
||||
}
|
||||
|
||||
XMessageBoxButton::XMessageBoxButton(const char* label, int clickVal)
|
||||
{
|
||||
strncpy(mLabel, label, LabelSize);
|
||||
mClickVal = clickVal;
|
||||
mLabelWidth = mX = mY = mWidth = mHeight = mMouseX = mMouseX = -1;
|
||||
mMouseDown = false;
|
||||
}
|
||||
|
||||
XMessageBox::XMessageBox(Display* display)
|
||||
{
|
||||
mMessage = "";
|
||||
mFS = NULL;
|
||||
mDisplay = display;
|
||||
}
|
||||
|
||||
XMessageBox::~XMessageBox()
|
||||
{
|
||||
clearMessageLines();
|
||||
if (mDisplay != NULL)
|
||||
{
|
||||
mDisplay = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int XMessageBox::alertOK(const char *windowTitle, const char *message)
|
||||
{
|
||||
mMessage = message;
|
||||
mTitle = windowTitle;
|
||||
mButtons.clear();
|
||||
mButtons.push_back(XMessageBoxButton("OK", OK));
|
||||
return show();
|
||||
}
|
||||
|
||||
int XMessageBox::alertOKCancel(const char *windowTitle, const char *message)
|
||||
{
|
||||
mMessage = message;
|
||||
mTitle = windowTitle;
|
||||
mButtons.clear();
|
||||
mButtons.push_back(XMessageBoxButton("OK", OK));
|
||||
mButtons.push_back(XMessageBoxButton("Cancel", Cancel));
|
||||
return show();
|
||||
}
|
||||
|
||||
int XMessageBox::alertRetryCancel(const char *windowTitle, const char *message)
|
||||
{
|
||||
mMessage = message;
|
||||
mTitle = windowTitle;
|
||||
mButtons.clear();
|
||||
mButtons.push_back(XMessageBoxButton("Retry", Retry));
|
||||
mButtons.push_back(XMessageBoxButton("Cancel", Cancel));
|
||||
return show();
|
||||
}
|
||||
|
||||
void XMessageBox::repaint()
|
||||
{
|
||||
int white = WhitePixel(mDisplay, DefaultScreen(mDisplay));
|
||||
int black = BlackPixel(mDisplay, DefaultScreen(mDisplay));
|
||||
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
|
||||
// line V margin
|
||||
y = y + MessageBox_LineVMargin * 2;
|
||||
|
||||
// line H margin
|
||||
x = MessageBox_LineHMargin;
|
||||
|
||||
XSetForeground(mDisplay, mGC, black);
|
||||
for (unsigned int i = 0; i < mMessageLines.size(); ++i)
|
||||
{
|
||||
XDrawString(mDisplay, mWin, mGC, x, y, mMessageLines[i],
|
||||
strlen(mMessageLines[i]));
|
||||
if (i < (mMessageLines.size() - 1))
|
||||
y = y + MessageBox_LineSpacer + mFontHeight;
|
||||
}
|
||||
XFlush(mDisplay);
|
||||
|
||||
// line V margin
|
||||
y = y + MessageBox_LineVMargin;
|
||||
|
||||
int maxButWidth = MessageBox_ButtonBoxWidth;
|
||||
int maxButHeight = MessageBox_ButtonBoxHeight;
|
||||
|
||||
// compute size of text labels on buttons
|
||||
int fgColor, bgColor;
|
||||
|
||||
int fontDirection, fontAscent, fontDescent;
|
||||
Vector<XMessageBoxButton>::iterator iter;
|
||||
for (iter = mButtons.begin(); iter != mButtons.end(); ++iter)
|
||||
{
|
||||
XCharStruct strInfo;
|
||||
XTextExtents(mFS, iter->getLabel(), strlen(iter->getLabel()),
|
||||
&fontDirection, &fontAscent, &fontDescent,
|
||||
&strInfo);
|
||||
// if (maxButWidth < strInfo.width)
|
||||
// maxButWidth = strInfo.width;
|
||||
// if (maxButHeight < (strInfo.ascent + strInfo.descent))
|
||||
// maxButHeight = (strInfo.ascent + strInfo.descent);
|
||||
iter->setLabelWidth(strInfo.width);
|
||||
}
|
||||
int buttonBoxWidth = maxButWidth;
|
||||
int buttonBoxHeight = maxButHeight;
|
||||
|
||||
// draw buttons
|
||||
// button V margin
|
||||
y = y + MessageBox_ButtonVMargin;
|
||||
|
||||
// center the buttons
|
||||
x = MessageBox_ButtonHMargin + (mMBWidth - getButtonLineWidth()) / 2;
|
||||
|
||||
for (iter = mButtons.begin(); iter != mButtons.end(); ++iter)
|
||||
{
|
||||
if (iter->drawReverse())
|
||||
{
|
||||
fgColor = white;
|
||||
bgColor = black;
|
||||
}
|
||||
else
|
||||
{
|
||||
fgColor = black;
|
||||
bgColor = white;
|
||||
}
|
||||
|
||||
XSetForeground(mDisplay, mGC, bgColor);
|
||||
XFillRectangle(mDisplay, mWin, mGC, x, y,
|
||||
buttonBoxWidth, buttonBoxHeight);
|
||||
XSetForeground(mDisplay, mGC, fgColor);
|
||||
XDrawRectangle(mDisplay, mWin, mGC, x, y,
|
||||
buttonBoxWidth, buttonBoxHeight);
|
||||
XDrawString(mDisplay, mWin, mGC,
|
||||
x + ((buttonBoxWidth - iter->getLabelWidth()) / 2),
|
||||
y + mFontAscent + ((buttonBoxHeight - mFontAscent) / 2),
|
||||
iter->getLabel(),
|
||||
strlen(iter->getLabel()));
|
||||
iter->setButtonRect(x, y, buttonBoxWidth, buttonBoxHeight);
|
||||
x = x + buttonBoxWidth + MessageBox_ButtonSpacer;
|
||||
}
|
||||
}
|
||||
|
||||
template <class Type>
|
||||
static inline Type max(Type v1, Type v2)
|
||||
{
|
||||
if (v1 <= v2)
|
||||
return v2;
|
||||
else
|
||||
return v1;
|
||||
}
|
||||
|
||||
template <class Type>
|
||||
static inline Type min(Type v1, Type v2)
|
||||
{
|
||||
if (v1 > v2)
|
||||
return v2;
|
||||
else
|
||||
return v1;
|
||||
}
|
||||
|
||||
void XMessageBox::clearMessageLines()
|
||||
{
|
||||
Vector<char*>::iterator iter;
|
||||
for (iter = mMessageLines.begin(); iter != mMessageLines.end(); ++iter)
|
||||
delete [] *iter;
|
||||
mMessageLines.clear();
|
||||
}
|
||||
|
||||
void XMessageBox::splitMessage()
|
||||
{
|
||||
clearMessageLines();
|
||||
if (mMessage == NULL || strlen(mMessage)==0)
|
||||
// JMQTODO: what to do with empty strings?
|
||||
return;
|
||||
|
||||
// need to break message up in to lines, and store lines in
|
||||
// mMessageLines
|
||||
|
||||
int numChars = strlen(mMessage);
|
||||
const int ScratchBufSize = 2048;
|
||||
char scratchBuf[ScratchBufSize];
|
||||
memset(scratchBuf, 0, ScratchBufSize);
|
||||
|
||||
int fontDirection, fontAscent, fontDescent;
|
||||
XCharStruct strInfo;
|
||||
|
||||
char *curChar = const_cast<char*>(mMessage);
|
||||
char *endChar;
|
||||
char *curWrapped = scratchBuf;
|
||||
int curWidth = 0;
|
||||
int maxWidth = mMaxWindowWidth - (MessageBox_LineHMargin);
|
||||
|
||||
while ( // while pointers are in range...
|
||||
(curChar - mMessage) < numChars &&
|
||||
(curWrapped - scratchBuf) < ScratchBufSize)
|
||||
{
|
||||
// look for next space in remaining string
|
||||
endChar = index(curChar, ' ');
|
||||
if (endChar == NULL)
|
||||
endChar = index(curChar, '\0');
|
||||
|
||||
if (endChar != NULL)
|
||||
// increment one char past the space to include it
|
||||
endChar++;
|
||||
else
|
||||
// otherwise, set the endchar to one char ahead
|
||||
endChar = curChar + 1;
|
||||
|
||||
// compute length of substr
|
||||
int len = endChar - curChar;
|
||||
XTextExtents(mFS, curChar, len,
|
||||
&fontDirection, &fontAscent, &fontDescent,
|
||||
&strInfo);
|
||||
// if its too big, time to add a new line...
|
||||
if ((curWidth + strInfo.width) > maxWidth)
|
||||
{
|
||||
// create a new block for the line and add it
|
||||
*curWrapped = '\0';
|
||||
int len = strlen(scratchBuf);
|
||||
char* line = new char[len+1];
|
||||
strncpy(line, scratchBuf, len+1); // +1 gets the null char
|
||||
mMessageLines.push_back(line);
|
||||
|
||||
// reset curWrapped to the beginning of the scratch buffer
|
||||
curWrapped = scratchBuf;
|
||||
curWidth = 0;
|
||||
}
|
||||
// copy the current string into curWrapped if we have enough room
|
||||
int bytesRemaining =
|
||||
ScratchBufSize - (curWrapped - scratchBuf);
|
||||
if (bytesRemaining >= len)
|
||||
strncpy(curWrapped, curChar, len);
|
||||
|
||||
curWrapped += len;
|
||||
curWidth += strInfo.width;
|
||||
curChar = endChar;
|
||||
}
|
||||
|
||||
// make a final line out of any leftover stuff in the scratch buffer
|
||||
if (curWrapped != scratchBuf)
|
||||
{
|
||||
*curWrapped = '\0';
|
||||
int len = strlen(scratchBuf);
|
||||
char* line = new char[len+1];
|
||||
strncpy(line, scratchBuf, len+1); // +1 gets the null char
|
||||
mMessageLines.push_back(line);
|
||||
}
|
||||
}
|
||||
|
||||
int XMessageBox::loadFont()
|
||||
{
|
||||
// load the font
|
||||
mFS = XLoadQueryFont(mDisplay,
|
||||
"-*-helvetica-medium-r-*-*-12-*-*-*-*-*-*-*");
|
||||
|
||||
if (mFS == NULL)
|
||||
mFS = XLoadQueryFont(mDisplay, "fixed");
|
||||
|
||||
if (mFS == NULL)
|
||||
return -1;
|
||||
|
||||
// dummy call to XTextExtents to get the font specs
|
||||
XCharStruct strInfo;
|
||||
|
||||
XTextExtents(mFS, "foo", 1,
|
||||
&mFontDirection, &mFontAscent, &mFontDescent,
|
||||
&strInfo);
|
||||
|
||||
mFontHeight = mFontAscent + mFontDescent;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int XMessageBox::getButtonLineWidth()
|
||||
{
|
||||
return mButtons.size() * MessageBox_ButtonBoxWidth +
|
||||
(mButtons.size() - 1) * MessageBox_ButtonSpacer +
|
||||
MessageBox_ButtonHMargin * 2;
|
||||
}
|
||||
|
||||
void XMessageBox::setDimensions()
|
||||
{
|
||||
mMBWidth = MessageBox_MaxWinWidth;
|
||||
mMBHeight = MessageBox_MaxWinHeight;
|
||||
|
||||
// determine width of button line
|
||||
int buttonWidth = getButtonLineWidth();
|
||||
|
||||
// if there is only one line, the desired width is the greater of the
|
||||
// line width and the buttonWidth, otherwise the lineWidth is the
|
||||
// max possible width which we already set.
|
||||
if (mMessageLines.size() == 1)
|
||||
{
|
||||
XCharStruct strInfo;
|
||||
int fontDirection, fontAscent, fontDescent;
|
||||
|
||||
XTextExtents(mFS, mMessageLines[0], strlen(mMessageLines[0]),
|
||||
&fontDirection, &fontAscent, &fontDescent,
|
||||
&strInfo);
|
||||
|
||||
mMBWidth = max(MessageBox_LineHMargin * 2 + strInfo.width,
|
||||
buttonWidth);
|
||||
mMBWidth = max(mMBWidth, MessageBox_MinWinWidth);
|
||||
}
|
||||
|
||||
// determine the height of the button line
|
||||
int buttonHeight = MessageBox_ButtonBoxHeight +
|
||||
MessageBox_ButtonVMargin * 2;
|
||||
|
||||
int lineHeight = mFontHeight * mMessageLines.size() +
|
||||
(mMessageLines.size() - 1) * MessageBox_LineSpacer +
|
||||
MessageBox_LineVMargin * 2;
|
||||
|
||||
mMBHeight = buttonHeight + lineHeight;
|
||||
}
|
||||
|
||||
int XMessageBox::show()
|
||||
{
|
||||
if (mDisplay == NULL)
|
||||
return -1;
|
||||
|
||||
int retVal = 0;
|
||||
retVal = loadFont();
|
||||
if (retVal < 0)
|
||||
return retVal;
|
||||
|
||||
// set the maximum window dimensions
|
||||
mScreenWidth = DisplayWidth(mDisplay, DefaultScreen(mDisplay));
|
||||
mScreenHeight = DisplayHeight(mDisplay, DefaultScreen(mDisplay));
|
||||
mMaxWindowWidth = min(mScreenWidth, MessageBox_MaxWinWidth);
|
||||
mMaxWindowHeight = min(mScreenHeight, MessageBox_MaxWinHeight);
|
||||
|
||||
// split the message into a vector of lines
|
||||
splitMessage();
|
||||
|
||||
// set the dialog dimensions
|
||||
setDimensions();
|
||||
|
||||
mWin = XCreateSimpleWindow(
|
||||
mDisplay,
|
||||
DefaultRootWindow(mDisplay),
|
||||
(mScreenWidth - mMBWidth) / 2, (mScreenHeight - mMBHeight) / 2,
|
||||
mMBWidth, mMBHeight,
|
||||
1,
|
||||
BlackPixel(mDisplay, DefaultScreen(mDisplay)),
|
||||
WhitePixel(mDisplay, DefaultScreen(mDisplay)));
|
||||
|
||||
mGC = XCreateGC(mDisplay, mWin, 0, 0);
|
||||
|
||||
XSetFont(mDisplay, mGC, mFS->fid);
|
||||
|
||||
// set input mask
|
||||
XSelectInput(mDisplay, mWin,
|
||||
ExposureMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask);
|
||||
|
||||
// set wm protocols in case they hit X
|
||||
Atom wm_delete_window =
|
||||
XInternAtom(mDisplay, "WM_DELETE_WINDOW", False);
|
||||
Atom wm_protocols =
|
||||
XInternAtom(mDisplay, "WM_PROTOCOLS", False);
|
||||
XSetWMProtocols (mDisplay, mWin, &wm_delete_window, 1);
|
||||
// set pop up dialog hint
|
||||
XSetTransientForHint(mDisplay, mWin, mWin);
|
||||
|
||||
// set title
|
||||
XTextProperty wtitle;
|
||||
wtitle.value = (unsigned char *)mTitle;
|
||||
wtitle.encoding = XA_STRING;
|
||||
wtitle.format = 8;
|
||||
wtitle.nitems = strlen(mTitle);
|
||||
XSetWMName(mDisplay, mWin, &wtitle);
|
||||
|
||||
// show window
|
||||
XMapWindow(mDisplay, mWin);
|
||||
// move it in case some bozo window manager repositioned it
|
||||
XMoveWindow(mDisplay, mWin,
|
||||
(mScreenWidth - mMBWidth) / 2, (mScreenHeight - mMBHeight) / 2);
|
||||
// raise it to top
|
||||
XRaiseWindow(mDisplay, mWin);
|
||||
|
||||
XMessageBoxButton* clickedButton = NULL;
|
||||
XEvent event;
|
||||
Vector<XMessageBoxButton>::iterator iter;
|
||||
bool done = false;
|
||||
while (!done)
|
||||
{
|
||||
XNextEvent(mDisplay, &event);
|
||||
switch (event.type)
|
||||
{
|
||||
case Expose:
|
||||
repaint();
|
||||
break;
|
||||
case MotionNotify:
|
||||
for (iter = mButtons.begin(); iter != mButtons.end(); ++iter)
|
||||
iter->setMouseCoordinates(event.xmotion.x, event.xmotion.y);
|
||||
break;
|
||||
case ButtonPress:
|
||||
for (iter = mButtons.begin(); iter != mButtons.end(); ++iter)
|
||||
{
|
||||
if (iter->pointInRect(event.xbutton.x, event.xbutton.y))
|
||||
{
|
||||
iter->setMouseDown(true);
|
||||
iter->setMouseCoordinates(event.xbutton.x, event.xbutton.y);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ButtonRelease:
|
||||
for (iter = mButtons.begin(); iter != mButtons.end(); ++iter)
|
||||
{
|
||||
if (iter->pointInRect(event.xbutton.x, event.xbutton.y) &&
|
||||
iter->isMouseDown())
|
||||
{
|
||||
// we got a winner!
|
||||
clickedButton = iter;
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (clickedButton == NULL)
|
||||
{
|
||||
// user released outside a button. clear the button states
|
||||
for (iter = mButtons.begin(); iter != mButtons.end(); ++iter)
|
||||
iter->setMouseDown(false);
|
||||
}
|
||||
break;
|
||||
case ClientMessage:
|
||||
if (event.xclient.message_type == wm_protocols &&
|
||||
event.xclient.data.l[0] == static_cast<long>(wm_delete_window))
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
XUnmapWindow(mDisplay, mWin);
|
||||
XDestroyWindow(mDisplay, mWin);
|
||||
XFreeGC(mDisplay, mGC);
|
||||
XFreeFont(mDisplay, mFS);
|
||||
|
||||
if (clickedButton != NULL)
|
||||
return clickedButton->getClickVal();
|
||||
else
|
||||
return -1;
|
||||
}
|
105
engine/platformX86UNIX/x86UNIXMessageBox.h
Executable file
105
engine/platformX86UNIX/x86UNIXMessageBox.h
Executable file
@ -0,0 +1,105 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
#ifndef _X86UNIXMESSAGEBOX_H_
|
||||
#define _X86UNIXMESSAGEBOX_H_
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include "core/tVector.h"
|
||||
|
||||
class XMessageBoxButton
|
||||
{
|
||||
public:
|
||||
XMessageBoxButton();
|
||||
XMessageBoxButton(const char* label, int clickVal);
|
||||
|
||||
const char *getLabel() { return static_cast<const char*>(mLabel); }
|
||||
int getClickVal() { return mClickVal; }
|
||||
|
||||
int getLabelWidth() { return mLabelWidth; }
|
||||
void setLabelWidth(int width) { mLabelWidth = width; }
|
||||
|
||||
void setButtonRect(int x, int y, int width, int height)
|
||||
{
|
||||
mX = x;
|
||||
mY = y;
|
||||
mWidth = width;
|
||||
mHeight = height;
|
||||
}
|
||||
void setMouseCoordinates(int x, int y)
|
||||
{
|
||||
mMouseX = x;
|
||||
mMouseY = y;
|
||||
}
|
||||
|
||||
bool drawReverse()
|
||||
{
|
||||
return mMouseDown && pointInRect(mMouseX, mMouseY);
|
||||
}
|
||||
|
||||
bool pointInRect(int x, int y)
|
||||
{
|
||||
if (x >= mX && x <= (mX+mWidth) &&
|
||||
y >= mY && y <= (mY+mHeight))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void setMouseDown(bool mouseDown) { mMouseDown = mouseDown; }
|
||||
bool isMouseDown() { return mMouseDown; }
|
||||
|
||||
private:
|
||||
static const int LabelSize = 100;
|
||||
char mLabel[LabelSize];
|
||||
int mClickVal;
|
||||
int mLabelWidth;
|
||||
int mX, mY, mWidth, mHeight;
|
||||
int mMouseX, mMouseY;
|
||||
bool mMouseDown;
|
||||
};
|
||||
|
||||
class XMessageBox
|
||||
{
|
||||
public:
|
||||
static const int OK = 1;
|
||||
static const int Cancel = 2;
|
||||
static const int Retry = 3;
|
||||
|
||||
XMessageBox(Display* display);
|
||||
~XMessageBox();
|
||||
|
||||
int alertOK(const char *windowTitle, const char *message);
|
||||
int alertOKCancel(const char *windowTitle, const char *message);
|
||||
int alertRetryCancel(const char *windowTitle, const char *message);
|
||||
private:
|
||||
int show();
|
||||
void repaint();
|
||||
void splitMessage();
|
||||
void clearMessageLines();
|
||||
int loadFont();
|
||||
void setDimensions();
|
||||
int getButtonLineWidth();
|
||||
|
||||
const char* mMessage;
|
||||
const char* mTitle;
|
||||
Vector<XMessageBoxButton> mButtons;
|
||||
Vector<char*> mMessageLines;
|
||||
|
||||
Display* mDisplay;
|
||||
GC mGC;
|
||||
Window mWin;
|
||||
XFontStruct* mFS;
|
||||
int mFontHeight;
|
||||
int mFontAscent;
|
||||
int mFontDescent;
|
||||
int mFontDirection;
|
||||
|
||||
int mScreenWidth, mScreenHeight, mMaxWindowWidth, mMaxWindowHeight;
|
||||
int mMBWidth, mMBHeight;
|
||||
};
|
||||
|
||||
#endif // #define _X86UNIXMESSAGEBOX_H_
|
136
engine/platformX86UNIX/x86UNIXMutex.cc
Executable file
136
engine/platformX86UNIX/x86UNIXMutex.cc
Executable file
@ -0,0 +1,136 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
#include "console/console.h"
|
||||
#include "platformX86UNIX/platformX86UNIX.h"
|
||||
#include "platform/platformMutex.h"
|
||||
#include "platformX86UNIX/x86UNIXMutex.h"
|
||||
|
||||
#include <pthread.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
void * Mutex::createMutex()
|
||||
{
|
||||
pthread_mutex_t *mutex;
|
||||
pthread_mutexattr_t attr;
|
||||
|
||||
pthread_mutexattr_init(&attr);
|
||||
pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE);
|
||||
|
||||
mutex = new pthread_mutex_t;
|
||||
pthread_mutex_init(mutex, &attr);
|
||||
|
||||
return((void*)mutex);
|
||||
}
|
||||
|
||||
void Mutex::destroyMutex(void * mutex)
|
||||
{
|
||||
pthread_mutex_t *pt_mutex = reinterpret_cast<pthread_mutex_t*>(mutex);
|
||||
AssertFatal(pt_mutex, "Mutex::destroyMutex: invalid mutex");
|
||||
pthread_mutex_destroy(pt_mutex);
|
||||
delete pt_mutex;
|
||||
}
|
||||
|
||||
bool Mutex::lockMutex(void * mutex, bool block)
|
||||
{
|
||||
pthread_mutex_t *pt_mutex = reinterpret_cast<pthread_mutex_t*>(mutex);
|
||||
AssertFatal(pt_mutex, "Mutex::lockMutex: invalid mutex");
|
||||
if(block)
|
||||
{
|
||||
return pthread_mutex_lock(pt_mutex) == 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return pthread_mutex_trylock(pt_mutex) == 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Mutex::unlockMutex(void * mutex)
|
||||
{
|
||||
pthread_mutex_t *pt_mutex = reinterpret_cast<pthread_mutex_t*>(mutex);
|
||||
AssertFatal(pt_mutex, "Mutex::unlockMutex: invalid mutex");
|
||||
pthread_mutex_unlock(pt_mutex);
|
||||
}
|
||||
|
||||
ProcessMutex::ProcessMutex()
|
||||
{
|
||||
mFD = -1;
|
||||
}
|
||||
|
||||
ProcessMutex::~ProcessMutex()
|
||||
{
|
||||
release();
|
||||
}
|
||||
|
||||
bool ProcessMutex::acquire(const char *mutexName)
|
||||
{
|
||||
if (mFD != -1)
|
||||
return false;
|
||||
|
||||
dSprintf(
|
||||
mLockFileName, LockFileNameSize,
|
||||
"/tmp/%s.lock", mutexName);
|
||||
|
||||
mFD = open(mLockFileName,
|
||||
O_CREAT | O_RDWR,
|
||||
S_IRUSR | S_IRGRP | S_IROTH |
|
||||
S_IWUSR | S_IWGRP | S_IWOTH);
|
||||
|
||||
if (mFD == -1)
|
||||
{
|
||||
Con::printf("Couldn't open file: %s", mLockFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
struct flock lock;
|
||||
//lock.l_type = F_RDLCK;
|
||||
lock.l_type = F_WRLCK;
|
||||
lock.l_whence = SEEK_SET;
|
||||
lock.l_start = 0;
|
||||
lock.l_len = 0;
|
||||
lock.l_pid = getpid();
|
||||
|
||||
if (fcntl(mFD, F_SETLK, &lock) == -1)
|
||||
{
|
||||
Con::printf("Couldn't lock file: %s, %s",
|
||||
mLockFileName, strerror(errno));
|
||||
if (fcntl(mFD, F_GETLK, &lock) != -1)
|
||||
Con::printf("Lock owned by pid: %d", lock.l_pid);
|
||||
Con::printf("Remove the file if lock is stale");
|
||||
close(mFD);
|
||||
mFD = -1;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void ProcessMutex::release()
|
||||
{
|
||||
if (mFD != -1)
|
||||
{
|
||||
close(mFD);
|
||||
mFD = -1;
|
||||
unlink(mLockFileName);
|
||||
}
|
||||
}
|
||||
|
||||
ConsoleFunction(debug_testx86unixmutex, void, 1, 1, "debug_testx86unixmutex()")
|
||||
{
|
||||
void* mutex = Mutex::createMutex();
|
||||
AssertFatal(mutex, "couldn't create mutex");
|
||||
Con::printf("created mutex");
|
||||
Mutex::lockMutex(mutex);
|
||||
Con::printf("locked mutex");
|
||||
Mutex::unlockMutex(mutex);
|
||||
Con::printf("unlocked mutex");
|
||||
Mutex::destroyMutex(mutex);
|
||||
Con::printf("destroyed mutex");
|
||||
}
|
||||
|
26
engine/platformX86UNIX/x86UNIXMutex.h
Executable file
26
engine/platformX86UNIX/x86UNIXMutex.h
Executable file
@ -0,0 +1,26 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
#ifndef _X86UNIXMUTEX_H_
|
||||
#define _X86UNIXMUTEX_H_
|
||||
|
||||
// A process-shared mutex class, used by Platform::excludeOtherInstances()
|
||||
class ProcessMutex
|
||||
{
|
||||
public:
|
||||
ProcessMutex();
|
||||
~ProcessMutex();
|
||||
|
||||
bool acquire(const char *mutexName);
|
||||
void release();
|
||||
private:
|
||||
int mFD;
|
||||
static const int LockFileNameSize=256;
|
||||
char mLockFileName[LockFileNameSize];
|
||||
};
|
||||
|
||||
#endif
|
908
engine/platformX86UNIX/x86UNIXNet.cc
Executable file
908
engine/platformX86UNIX/x86UNIXNet.cc
Executable file
@ -0,0 +1,908 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
//
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
#include "platformX86UNIX/platformX86UNIX.h"
|
||||
#include "platform/platform.h"
|
||||
#include "platform/event.h"
|
||||
#include "platform/platformNetAsync.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/poll.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <errno.h>
|
||||
|
||||
/* for PROTO_IPX */
|
||||
#if defined(__linux__)
|
||||
#include <net/if_ppp.h>
|
||||
#include <sys/ioctl.h> /* ioctl() */
|
||||
#include <net/ppp_defs.h>
|
||||
#elif defined(__OpenBSD__) || defined(__FreeBSD__)
|
||||
#include <sys/ioctl.h> /* ioctl() */
|
||||
#include <net/ppp_defs.h>
|
||||
#endif
|
||||
|
||||
#include <netipx/ipx.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "console/console.h"
|
||||
#include "platform/gameInterface.h"
|
||||
#include "core/fileStream.h"
|
||||
#include "core/tVector.h"
|
||||
|
||||
static Net::Error getLastError();
|
||||
static S32 defaultPort = 28000;
|
||||
static S32 netPort = 0;
|
||||
static int ipxSocket = InvalidSocket;
|
||||
static int udpSocket = InvalidSocket;
|
||||
|
||||
// local enum for socket states for polled sockets
|
||||
enum SocketState
|
||||
{
|
||||
InvalidState,
|
||||
Connected,
|
||||
ConnectionPending,
|
||||
Listening,
|
||||
NameLookupRequired
|
||||
};
|
||||
|
||||
// the Socket structure helps us keep track of the
|
||||
// above states
|
||||
struct Socket
|
||||
{
|
||||
Socket()
|
||||
{
|
||||
fd = InvalidSocket;
|
||||
state = InvalidState;
|
||||
remoteAddr[0] = 0;
|
||||
remotePort = -1;
|
||||
}
|
||||
|
||||
NetSocket fd;
|
||||
S32 state;
|
||||
char remoteAddr[256];
|
||||
S32 remotePort;
|
||||
};
|
||||
|
||||
// list of polled sockets
|
||||
static Vector<Socket*> gPolledSockets;
|
||||
|
||||
static Socket* addPolledSocket(NetSocket& fd, S32 state,
|
||||
char* remoteAddr = NULL, S32 port = -1)
|
||||
{
|
||||
Socket* sock = new Socket();
|
||||
sock->fd = fd;
|
||||
sock->state = state;
|
||||
if (remoteAddr)
|
||||
dStrcpy(sock->remoteAddr, remoteAddr);
|
||||
if (port != -1)
|
||||
sock->remotePort = port;
|
||||
gPolledSockets.push_back(sock);
|
||||
return sock;
|
||||
}
|
||||
|
||||
enum {
|
||||
MaxConnections = 1024,
|
||||
};
|
||||
|
||||
S32 Poll(NetSocket fd, S32 eventMask, S32 timeoutMs)
|
||||
{
|
||||
pollfd pfd;
|
||||
S32 retVal;
|
||||
pfd.fd = fd;
|
||||
pfd.events = eventMask;
|
||||
|
||||
retVal = poll(&pfd, 1, timeoutMs);
|
||||
return retVal;
|
||||
if (retVal <= 0)
|
||||
return retVal;
|
||||
else
|
||||
return pfd.revents;
|
||||
}
|
||||
|
||||
bool Net::init()
|
||||
{
|
||||
NetAsync::startAsync();
|
||||
return(true);
|
||||
}
|
||||
|
||||
void Net::shutdown()
|
||||
{
|
||||
while (gPolledSockets.size() > 0)
|
||||
closeConnectTo(gPolledSockets[0]->fd);
|
||||
|
||||
closePort();
|
||||
NetAsync::stopAsync();
|
||||
}
|
||||
|
||||
static void netToIPSocketAddress(const NetAddress *address, struct sockaddr_in *sockAddr)
|
||||
{
|
||||
dMemset(sockAddr, 0, sizeof(struct sockaddr_in));
|
||||
sockAddr->sin_family = AF_INET;
|
||||
sockAddr->sin_port = htons(address->port);
|
||||
char tAddr[20];
|
||||
dSprintf(tAddr, 20, "%d.%d.%d.%d\n", address->netNum[0], address->netNum[1], address->netNum[2], address->netNum[3]);
|
||||
//fprintf(stdout,"netToIPSocketAddress(): %s\n",tAddr);fflush(NULL);
|
||||
sockAddr->sin_addr.s_addr = inet_addr(tAddr);
|
||||
// sockAddr->sin_addr.s_addr = address->netNum[0]; // hopefully this will work.
|
||||
}
|
||||
|
||||
static void IPSocketToNetAddress(const struct sockaddr_in *sockAddr, NetAddress *address)
|
||||
{
|
||||
address->type = NetAddress::IPAddress;
|
||||
address->port = htons(sockAddr->sin_port);
|
||||
char *tAddr;
|
||||
tAddr = inet_ntoa(sockAddr->sin_addr);
|
||||
//fprintf(stdout,"IPSocketToNetAddress(): %s\n",tAddr);fflush(NULL);
|
||||
U8 nets[4];
|
||||
nets[0] = atoi(strtok(tAddr, "."));
|
||||
nets[1] = atoi(strtok(NULL, "."));
|
||||
nets[2] = atoi(strtok(NULL, "."));
|
||||
nets[3] = atoi(strtok(NULL, "."));
|
||||
//fprintf(stdout,"0 = %d, 1 = %d, 2 = %d, 3 = %d\n", nets[0], nets[1], nets[2], nets[3]);
|
||||
address->netNum[0] = nets[0];
|
||||
address->netNum[1] = nets[1];
|
||||
address->netNum[2] = nets[2];
|
||||
address->netNum[3] = nets[3];
|
||||
}
|
||||
|
||||
static void netToIPXSocketAddress(const NetAddress *address, sockaddr_ipx *sockAddr)
|
||||
{
|
||||
#if !defined(__FreeBSD__)
|
||||
dMemset(sockAddr, 0, sizeof(sockaddr_ipx));
|
||||
sockAddr->sipx_family = AF_INET;
|
||||
sockAddr->sipx_port = htons(address->port);
|
||||
sockAddr->sipx_network = address->netNum[0];
|
||||
sockAddr->sipx_node[0] = address->nodeNum[0];
|
||||
sockAddr->sipx_node[1] = address->nodeNum[1];
|
||||
sockAddr->sipx_node[2] = address->nodeNum[2];
|
||||
sockAddr->sipx_node[3] = address->nodeNum[3];
|
||||
sockAddr->sipx_node[4] = address->nodeNum[4];
|
||||
sockAddr->sipx_node[5] = address->nodeNum[5];
|
||||
#endif
|
||||
}
|
||||
|
||||
static void IPXSocketToNetAddress(const sockaddr_ipx *sockAddr, NetAddress *address)
|
||||
{
|
||||
#if !defined(__FreeBSD__)
|
||||
address->type = NetAddress::IPXAddress;
|
||||
address->port = htons(sockAddr->sipx_port);
|
||||
address->netNum[0] = sockAddr->sipx_network;
|
||||
address->nodeNum[0] = sockAddr->sipx_node[0];
|
||||
address->nodeNum[1] = sockAddr->sipx_node[1];
|
||||
address->nodeNum[2] = sockAddr->sipx_node[2];
|
||||
address->nodeNum[3] = sockAddr->sipx_node[3];
|
||||
address->nodeNum[4] = sockAddr->sipx_node[4];
|
||||
address->nodeNum[5] = sockAddr->sipx_node[5];
|
||||
#endif
|
||||
}
|
||||
|
||||
NetSocket Net::openListenPort(U16 port)
|
||||
{
|
||||
if(Game->isJournalReading())
|
||||
{
|
||||
U32 ret;
|
||||
Game->journalRead(&ret);
|
||||
return NetSocket(ret);
|
||||
}
|
||||
NetSocket sock = openSocket();
|
||||
if (sock == InvalidSocket)
|
||||
{
|
||||
Con::errorf("Unable to open listen socket: %s", strerror(errno));
|
||||
return InvalidSocket;
|
||||
}
|
||||
|
||||
if (bind(sock, port) != NoError)
|
||||
{
|
||||
Con::errorf("Unable to bind port %d: %s", port, strerror(errno));
|
||||
::close(sock);
|
||||
return InvalidSocket;
|
||||
}
|
||||
if (listen(sock, 4) != NoError)
|
||||
{
|
||||
Con::errorf("Unable to listen on port %d: %s", port, strerror(errno));
|
||||
::close(sock);
|
||||
return InvalidSocket;
|
||||
}
|
||||
|
||||
setBlocking(sock, false);
|
||||
addPolledSocket(sock, Listening);
|
||||
if (Game->isJournalWriting())
|
||||
Game->journalWrite(U32(sock));
|
||||
return sock;
|
||||
}
|
||||
|
||||
NetSocket Net::openConnectTo(const char *addressString)
|
||||
{
|
||||
if(!dStrnicmp(addressString, "ipx:", 4))
|
||||
return InvalidSocket;
|
||||
if(!dStrnicmp(addressString, "ip:", 3))
|
||||
addressString += 3; // eat off the ip:
|
||||
char remoteAddr[256];
|
||||
dStrcpy(remoteAddr, addressString);
|
||||
|
||||
char *portString = dStrchr(remoteAddr, ':');
|
||||
|
||||
U16 port;
|
||||
if(portString)
|
||||
{
|
||||
*portString++ = 0;
|
||||
port = htons(dAtoi(portString));
|
||||
}
|
||||
else
|
||||
port = htons(defaultPort);
|
||||
|
||||
if(!dStricmp(remoteAddr, "broadcast"))
|
||||
return InvalidSocket;
|
||||
|
||||
if(Game->isJournalReading())
|
||||
{
|
||||
U32 ret;
|
||||
Game->journalRead(&ret);
|
||||
return NetSocket(ret);
|
||||
}
|
||||
NetSocket sock = openSocket();
|
||||
setBlocking(sock, false);
|
||||
|
||||
sockaddr_in ipAddr;
|
||||
dMemset(&ipAddr, 0, sizeof(ipAddr));
|
||||
|
||||
if (inet_aton(remoteAddr, &ipAddr.sin_addr) != 0)
|
||||
{
|
||||
ipAddr.sin_port = port;
|
||||
ipAddr.sin_family = AF_INET;
|
||||
if(::connect(sock, (struct sockaddr *)&ipAddr, sizeof(ipAddr)) == -1 &&
|
||||
errno != EINPROGRESS)
|
||||
{
|
||||
Con::errorf("Error connecting %s: %s",
|
||||
addressString, strerror(errno));
|
||||
::close(sock);
|
||||
sock = InvalidSocket;
|
||||
}
|
||||
if(sock != InvalidSocket) {
|
||||
// add this socket to our list of polled sockets
|
||||
addPolledSocket(sock, ConnectionPending);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// need to do an asynchronous name lookup. first, add the socket
|
||||
// to the polled list
|
||||
addPolledSocket(sock, NameLookupRequired, remoteAddr, port);
|
||||
// queue the lookup
|
||||
gNetAsync.queueLookup(remoteAddr, sock);
|
||||
}
|
||||
if(Game->isJournalWriting())
|
||||
Game->journalWrite(U32(sock));
|
||||
return sock;
|
||||
}
|
||||
|
||||
void Net::closeConnectTo(NetSocket sock)
|
||||
{
|
||||
if(Game->isJournalReading())
|
||||
return;
|
||||
|
||||
// if this socket is in the list of polled sockets, remove it
|
||||
for (int i = 0; i < gPolledSockets.size(); ++i)
|
||||
if (gPolledSockets[i]->fd == sock)
|
||||
{
|
||||
delete gPolledSockets[i];
|
||||
gPolledSockets.erase(i);
|
||||
break;
|
||||
}
|
||||
|
||||
closeSocket(sock);
|
||||
}
|
||||
|
||||
Net::Error Net::sendtoSocket(NetSocket socket, const U8 *buffer, int bufferSize)
|
||||
{
|
||||
if(Game->isJournalReading())
|
||||
{
|
||||
U32 e;
|
||||
Game->journalRead(&e);
|
||||
|
||||
return (Net::Error) e;
|
||||
}
|
||||
Net::Error e = send(socket, buffer, bufferSize);
|
||||
if(Game->isJournalWriting())
|
||||
Game->journalWrite(U32(e));
|
||||
return e;
|
||||
}
|
||||
|
||||
bool Net::openPort(S32 port)
|
||||
{
|
||||
if(udpSocket != InvalidSocket)
|
||||
close(udpSocket);
|
||||
if(ipxSocket != InvalidSocket)
|
||||
close(ipxSocket);
|
||||
|
||||
udpSocket = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
ipxSocket = socket(AF_IPX, SOCK_DGRAM, 0);
|
||||
|
||||
if(udpSocket != InvalidSocket)
|
||||
{
|
||||
Net::Error error;
|
||||
error = bind(udpSocket, port);
|
||||
if(error == NoError)
|
||||
error = setBufferSize(udpSocket, 32768);
|
||||
if(error == NoError)
|
||||
error = setBroadcast(udpSocket, true);
|
||||
if(error == NoError)
|
||||
error = setBlocking(udpSocket, false);
|
||||
if(error == NoError)
|
||||
Con::printf("UDP initialized on port %d", port);
|
||||
else
|
||||
{
|
||||
close(udpSocket);
|
||||
udpSocket = InvalidSocket;
|
||||
Con::printf("Unable to initialize UDP - error %d", error);
|
||||
}
|
||||
}
|
||||
if(ipxSocket != InvalidSocket)
|
||||
{
|
||||
Net::Error error = NoError;
|
||||
sockaddr_ipx ipxAddress;
|
||||
memset((char *)&ipxAddress, 0, sizeof(ipxAddress));
|
||||
ipxAddress.sipx_family = AF_IPX;
|
||||
ipxAddress.sipx_port = htons(port);
|
||||
S32 err = ::bind(ipxSocket, (struct sockaddr *)&ipxAddress, sizeof(ipxAddress));
|
||||
if(err)
|
||||
error = getLastError();
|
||||
if(error == NoError)
|
||||
error = setBufferSize(ipxSocket, 32768);
|
||||
if(error == NoError)
|
||||
error = setBroadcast(ipxSocket, true);
|
||||
if(error == NoError)
|
||||
error = setBlocking(ipxSocket, false);
|
||||
if(error == NoError)
|
||||
Con::printf("IPX initialized on port %d", port);
|
||||
else
|
||||
{
|
||||
close(ipxSocket);
|
||||
ipxSocket = InvalidSocket;
|
||||
Con::printf("Unable to initialize IPX - error %d", error);
|
||||
}
|
||||
}
|
||||
netPort = port;
|
||||
return ipxSocket != InvalidSocket || udpSocket != InvalidSocket;
|
||||
}
|
||||
|
||||
void Net::closePort()
|
||||
{
|
||||
if(ipxSocket != InvalidSocket)
|
||||
close(ipxSocket);
|
||||
if(udpSocket != InvalidSocket)
|
||||
close(udpSocket);
|
||||
}
|
||||
|
||||
Net::Error Net::sendto(const NetAddress *address, const U8 *buffer, S32 bufferSize)
|
||||
{
|
||||
if(Game->isJournalReading())
|
||||
return NoError;
|
||||
|
||||
if(address->type == NetAddress::IPXAddress)
|
||||
{
|
||||
sockaddr_ipx ipxAddr;
|
||||
netToIPXSocketAddress(address, &ipxAddr);
|
||||
if(::sendto(ipxSocket, (const char*)buffer, bufferSize, 0,
|
||||
(sockaddr *) &ipxAddr, sizeof(sockaddr_ipx)) == -1)
|
||||
return getLastError();
|
||||
else
|
||||
return NoError;
|
||||
}
|
||||
else
|
||||
{
|
||||
sockaddr_in ipAddr;
|
||||
netToIPSocketAddress(address, &ipAddr);
|
||||
if(::sendto(udpSocket, (const char*)buffer, bufferSize, 0,
|
||||
(sockaddr *) &ipAddr, sizeof(sockaddr_in)) == -1)
|
||||
return getLastError();
|
||||
else
|
||||
return NoError;
|
||||
}
|
||||
}
|
||||
|
||||
void Net::process()
|
||||
{
|
||||
sockaddr sa;
|
||||
|
||||
PacketReceiveEvent receiveEvent;
|
||||
for(;;)
|
||||
{
|
||||
U32 addrLen = sizeof(sa);
|
||||
S32 bytesRead = -1;
|
||||
if(udpSocket != InvalidSocket)
|
||||
bytesRead = recvfrom(udpSocket, (char *) receiveEvent.data, MaxPacketDataSize, 0, &sa, &addrLen);
|
||||
if(bytesRead == -1 && ipxSocket != InvalidSocket)
|
||||
{
|
||||
addrLen = sizeof(sa);
|
||||
bytesRead = recvfrom(ipxSocket, (char *) receiveEvent.data, MaxPacketDataSize, 0, &sa, &addrLen);
|
||||
}
|
||||
|
||||
if(bytesRead == -1)
|
||||
break;
|
||||
|
||||
if(sa.sa_family == AF_INET)
|
||||
IPSocketToNetAddress((sockaddr_in *) &sa, &receiveEvent.sourceAddress);
|
||||
else if(sa.sa_family == AF_IPX)
|
||||
IPXSocketToNetAddress((sockaddr_ipx *) &sa, &receiveEvent.sourceAddress);
|
||||
else
|
||||
continue;
|
||||
|
||||
NetAddress &na = receiveEvent.sourceAddress;
|
||||
if(na.type == NetAddress::IPAddress &&
|
||||
na.netNum[0] == 127 &&
|
||||
na.netNum[1] == 0 &&
|
||||
na.netNum[2] == 0 &&
|
||||
na.netNum[3] == 1 &&
|
||||
na.port == netPort)
|
||||
continue;
|
||||
if(bytesRead <= 0)
|
||||
continue;
|
||||
receiveEvent.size = PacketReceiveEventHeaderSize + bytesRead;
|
||||
Game->postEvent(receiveEvent);
|
||||
}
|
||||
|
||||
// process the polled sockets. This blob of code performs functions
|
||||
// similar to WinsockProc in winNet.cc
|
||||
|
||||
if (gPolledSockets.size() == 0)
|
||||
return;
|
||||
|
||||
static ConnectedNotifyEvent notifyEvent;
|
||||
static ConnectedAcceptEvent acceptEvent;
|
||||
static ConnectedReceiveEvent cReceiveEvent;
|
||||
|
||||
S32 optval;
|
||||
socklen_t optlen = sizeof(S32);
|
||||
S32 bytesRead;
|
||||
Net::Error err;
|
||||
bool removeSock = false;
|
||||
Socket *currentSock = NULL;
|
||||
sockaddr_in ipAddr;
|
||||
NetSocket incoming = InvalidSocket;
|
||||
char out_h_addr[1024];
|
||||
int out_h_length = 0;
|
||||
|
||||
for (S32 i = 0; i < gPolledSockets.size();
|
||||
/* no increment, this is done at end of loop body */)
|
||||
{
|
||||
removeSock = false;
|
||||
currentSock = gPolledSockets[i];
|
||||
switch (currentSock->state)
|
||||
{
|
||||
case InvalidState:
|
||||
Con::errorf("Error, InvalidState socket in polled sockets list");
|
||||
break;
|
||||
case ConnectionPending:
|
||||
notifyEvent.tag = currentSock->fd;
|
||||
// see if it is now connected
|
||||
if (getsockopt(currentSock->fd, SOL_SOCKET, SO_ERROR,
|
||||
&optval, &optlen) == -1)
|
||||
{
|
||||
Con::errorf("Error getting socket options: %s", strerror(errno));
|
||||
notifyEvent.state = ConnectedNotifyEvent::ConnectFailed;
|
||||
Game->postEvent(notifyEvent);
|
||||
removeSock = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (optval == EINPROGRESS)
|
||||
// still connecting...
|
||||
break;
|
||||
|
||||
if (optval == 0)
|
||||
{
|
||||
// connected
|
||||
notifyEvent.state = ConnectedNotifyEvent::Connected;
|
||||
Game->postEvent(notifyEvent);
|
||||
currentSock->state = Connected;
|
||||
}
|
||||
else
|
||||
{
|
||||
// some kind of error
|
||||
Con::errorf("Error connecting: %s", strerror(errno));
|
||||
notifyEvent.state = ConnectedNotifyEvent::ConnectFailed;
|
||||
Game->postEvent(notifyEvent);
|
||||
removeSock = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Connected:
|
||||
bytesRead = 0;
|
||||
// try to get some data
|
||||
err = Net::recv(currentSock->fd, cReceiveEvent.data,
|
||||
MaxPacketDataSize, &bytesRead);
|
||||
if(err == Net::NoError)
|
||||
{
|
||||
if (bytesRead > 0)
|
||||
{
|
||||
// got some data, post it
|
||||
cReceiveEvent.tag = currentSock->fd;
|
||||
cReceiveEvent.size = ConnectedReceiveEventHeaderSize +
|
||||
bytesRead;
|
||||
Game->postEvent(cReceiveEvent);
|
||||
}
|
||||
else
|
||||
{
|
||||
// zero bytes read means EOF
|
||||
if (bytesRead < 0)
|
||||
// ack! this shouldn't happen
|
||||
Con::errorf("Unexpected error on socket: %s",
|
||||
strerror(errno));
|
||||
|
||||
notifyEvent.tag = currentSock->fd;
|
||||
notifyEvent.state = ConnectedNotifyEvent::Disconnected;
|
||||
Game->postEvent(notifyEvent);
|
||||
removeSock = true;
|
||||
}
|
||||
}
|
||||
else if (err != Net::NoError && err != Net::WouldBlock)
|
||||
{
|
||||
Con::errorf("Error reading from socket: %s", strerror(errno));
|
||||
notifyEvent.tag = currentSock->fd;
|
||||
notifyEvent.state = ConnectedNotifyEvent::Disconnected;
|
||||
Game->postEvent(notifyEvent);
|
||||
removeSock = true;
|
||||
}
|
||||
break;
|
||||
case NameLookupRequired:
|
||||
// is the lookup complete?
|
||||
if (!gNetAsync.checkLookup(
|
||||
currentSock->fd, out_h_addr, &out_h_length,
|
||||
sizeof(out_h_addr)))
|
||||
break;
|
||||
|
||||
notifyEvent.tag = currentSock->fd;
|
||||
if (out_h_length == -1)
|
||||
{
|
||||
Con::errorf("DNS lookup failed: %s", currentSock->remoteAddr);
|
||||
notifyEvent.state = ConnectedNotifyEvent::DNSFailed;
|
||||
removeSock = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// try to connect
|
||||
dMemcpy(&(ipAddr.sin_addr.s_addr), out_h_addr, out_h_length);
|
||||
ipAddr.sin_port = currentSock->remotePort;
|
||||
ipAddr.sin_family = AF_INET;
|
||||
if(::connect(currentSock->fd, (struct sockaddr *)&ipAddr,
|
||||
sizeof(ipAddr)) == -1)
|
||||
{
|
||||
if (errno == EINPROGRESS)
|
||||
{
|
||||
notifyEvent.state = ConnectedNotifyEvent::DNSResolved;
|
||||
currentSock->state = ConnectionPending;
|
||||
}
|
||||
else
|
||||
{
|
||||
Con::errorf("Error connecting to %s: %s",
|
||||
currentSock->remoteAddr, strerror(errno));
|
||||
notifyEvent.state = ConnectedNotifyEvent::ConnectFailed;
|
||||
removeSock = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
notifyEvent.state = ConnectedNotifyEvent::Connected;
|
||||
currentSock->state = Connected;
|
||||
}
|
||||
}
|
||||
Game->postEvent(notifyEvent);
|
||||
break;
|
||||
case Listening:
|
||||
incoming =
|
||||
Net::accept(currentSock->fd, &acceptEvent.address);
|
||||
if(incoming != InvalidSocket)
|
||||
{
|
||||
acceptEvent.portTag = currentSock->fd;
|
||||
acceptEvent.connectionTag = incoming;
|
||||
setBlocking(incoming, false);
|
||||
addPolledSocket(incoming, Connected);
|
||||
Game->postEvent(acceptEvent);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// only increment index if we're not removing the connection, since
|
||||
// the removal will shift the indices down by one
|
||||
if (removeSock)
|
||||
closeConnectTo(currentSock->fd);
|
||||
else
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
NetSocket Net::openSocket()
|
||||
{
|
||||
int retSocket;
|
||||
retSocket = socket(AF_INET, SOCK_STREAM, 0);
|
||||
|
||||
if(retSocket == InvalidSocket)
|
||||
return InvalidSocket;
|
||||
else
|
||||
return retSocket;
|
||||
}
|
||||
|
||||
Net::Error Net::closeSocket(NetSocket socket)
|
||||
{
|
||||
if(socket != InvalidSocket)
|
||||
{
|
||||
if(!close(socket))
|
||||
return NoError;
|
||||
else
|
||||
return getLastError();
|
||||
}
|
||||
else
|
||||
return NotASocket;
|
||||
}
|
||||
|
||||
Net::Error Net::connect(NetSocket socket, const NetAddress *address)
|
||||
{
|
||||
if(address->type != NetAddress::IPAddress)
|
||||
return WrongProtocolType;
|
||||
sockaddr_in socketAddress;
|
||||
netToIPSocketAddress(address, &socketAddress);
|
||||
if(!::connect(socket, (sockaddr *) &socketAddress, sizeof(socketAddress)))
|
||||
return NoError;
|
||||
return getLastError();
|
||||
}
|
||||
|
||||
Net::Error Net::listen(NetSocket socket, S32 backlog)
|
||||
{
|
||||
if(!::listen(socket, backlog))
|
||||
return NoError;
|
||||
return getLastError();
|
||||
}
|
||||
|
||||
NetSocket Net::accept(NetSocket acceptSocket, NetAddress *remoteAddress)
|
||||
{
|
||||
sockaddr_in socketAddress;
|
||||
U32 addrLen = sizeof(socketAddress);
|
||||
|
||||
int retVal = ::accept(acceptSocket, (sockaddr *) &socketAddress, &addrLen);
|
||||
if(retVal != InvalidSocket)
|
||||
{
|
||||
IPSocketToNetAddress(&socketAddress, remoteAddress);
|
||||
return retVal;
|
||||
}
|
||||
return InvalidSocket;
|
||||
}
|
||||
|
||||
Net::Error Net::bind(NetSocket socket, U16 port)
|
||||
{
|
||||
S32 error;
|
||||
|
||||
sockaddr_in socketAddress;
|
||||
dMemset((char *)&socketAddress, 0, sizeof(socketAddress));
|
||||
socketAddress.sin_family = AF_INET;
|
||||
// It's entirely possible that there are two NIC cards.
|
||||
// We let the user specify which one the server runs on.
|
||||
|
||||
// thanks to [TPG]P1aGu3 for the name
|
||||
const char* serverIP = Con::getVariable( "Pref::Net::BindAddress" );
|
||||
// serverIP is guaranteed to be non-0.
|
||||
AssertFatal( serverIP, "serverIP is NULL!" );
|
||||
|
||||
if( serverIP[0] != '\0' ) {
|
||||
// we're not empty
|
||||
socketAddress.sin_addr.s_addr = inet_addr( serverIP );
|
||||
|
||||
if( socketAddress.sin_addr.s_addr != INADDR_NONE ) {
|
||||
Con::printf( "Binding server port to %s", serverIP );
|
||||
} else {
|
||||
Con::warnf( ConsoleLogEntry::General,
|
||||
"inet_addr() failed for %s while binding!",
|
||||
serverIP );
|
||||
socketAddress.sin_addr.s_addr = INADDR_ANY;
|
||||
}
|
||||
|
||||
} else {
|
||||
Con::printf( "Binding server port to default IP" );
|
||||
socketAddress.sin_addr.s_addr = INADDR_ANY;
|
||||
}
|
||||
|
||||
socketAddress.sin_port = htons(port);
|
||||
error = ::bind(socket, (sockaddr *) &socketAddress, sizeof(socketAddress));
|
||||
|
||||
if(!error)
|
||||
return NoError;
|
||||
return getLastError();
|
||||
}
|
||||
|
||||
Net::Error Net::setBufferSize(NetSocket socket, S32 bufferSize)
|
||||
{
|
||||
S32 error;
|
||||
error = setsockopt(socket, SOL_SOCKET, SO_RCVBUF, (char *) &bufferSize, sizeof(bufferSize));
|
||||
if(!error)
|
||||
error = setsockopt(socket, SOL_SOCKET, SO_SNDBUF, (char *) &bufferSize, sizeof(bufferSize));
|
||||
if(!error)
|
||||
return NoError;
|
||||
return getLastError();
|
||||
}
|
||||
|
||||
Net::Error Net::setBroadcast(NetSocket socket, bool broadcast)
|
||||
{
|
||||
S32 bc = broadcast;
|
||||
S32 error = setsockopt(socket, SOL_SOCKET, SO_BROADCAST, (char*)&bc, sizeof(bc));
|
||||
if(!error)
|
||||
return NoError;
|
||||
return getLastError();
|
||||
}
|
||||
|
||||
Net::Error Net::setBlocking(NetSocket socket, bool blockingIO)
|
||||
{
|
||||
int notblock = !blockingIO;
|
||||
S32 error = ioctl(socket, FIONBIO, ¬block);
|
||||
if(!error)
|
||||
return NoError;
|
||||
return getLastError();
|
||||
}
|
||||
|
||||
Net::Error Net::send(NetSocket socket, const U8 *buffer, S32 bufferSize)
|
||||
{
|
||||
// Poll for write status. this blocks. should really
|
||||
// do this in a separate thread or set it up so that the data can
|
||||
// get queued and sent later
|
||||
// JMQTODO
|
||||
Poll(socket, POLLOUT, 10000);
|
||||
|
||||
S32 error = ::send(socket, (const char*)buffer, bufferSize, 0);
|
||||
if(error != -1)
|
||||
return NoError;
|
||||
|
||||
return getLastError();
|
||||
}
|
||||
|
||||
Net::Error Net::recv(NetSocket socket, U8 *buffer, S32 bufferSize, S32 *bytesRead)
|
||||
{
|
||||
*bytesRead = ::recv(socket, (char*)buffer, bufferSize, 0);
|
||||
if(*bytesRead == -1)
|
||||
return getLastError();
|
||||
return NoError;
|
||||
}
|
||||
|
||||
bool Net::compareAddresses(const NetAddress *a1, const NetAddress *a2)
|
||||
{
|
||||
if((a1->type != a2->type) ||
|
||||
(*((U32 *)a1->netNum) != *((U32 *)a2->netNum)) ||
|
||||
(a1->port != a2->port))
|
||||
return false;
|
||||
|
||||
if(a1->type == NetAddress::IPAddress)
|
||||
return true;
|
||||
for(S32 i = 0; i < 6; i++)
|
||||
if(a1->nodeNum[i] != a2->nodeNum[i])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Net::stringToAddress(const char *addressString, NetAddress *address)
|
||||
{
|
||||
if(dStrnicmp(addressString, "ipx:", 4))
|
||||
{
|
||||
// assume IP if it doesn't have ipx: at the front.
|
||||
|
||||
if(!dStrnicmp(addressString, "ip:", 3))
|
||||
addressString += 3; // eat off the ip:
|
||||
|
||||
sockaddr_in ipAddr;
|
||||
char remoteAddr[256];
|
||||
if(strlen(addressString) > 255)
|
||||
return false;
|
||||
|
||||
dStrcpy(remoteAddr, addressString);
|
||||
|
||||
char *portString = dStrchr(remoteAddr, ':');
|
||||
if(portString)
|
||||
*portString++ = '\0';
|
||||
|
||||
struct hostent *hp;
|
||||
if(!dStricmp(remoteAddr, "broadcast"))
|
||||
ipAddr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
|
||||
else
|
||||
{
|
||||
if (inet_aton(remoteAddr,&ipAddr.sin_addr) == 0) // error
|
||||
{
|
||||
if((hp = gethostbyname(remoteAddr)) == 0)
|
||||
return false;
|
||||
else
|
||||
memcpy(&ipAddr.sin_addr.s_addr, hp->h_addr, sizeof(in_addr));
|
||||
}
|
||||
}
|
||||
if(portString)
|
||||
ipAddr.sin_port = htons(dAtoi(portString));
|
||||
else
|
||||
ipAddr.sin_port = htons(defaultPort);
|
||||
ipAddr.sin_family = AF_INET;
|
||||
IPSocketToNetAddress(&ipAddr, address);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
S32 i;
|
||||
S32 port;
|
||||
|
||||
address->type = NetAddress::IPXAddress;
|
||||
for(i = 0; i < 6; i++)
|
||||
address->nodeNum[i] = 0xFF;
|
||||
|
||||
// it's an IPX string
|
||||
addressString += 4;
|
||||
if(!dStricmp(addressString, "broadcast"))
|
||||
{
|
||||
address->port = defaultPort;
|
||||
return true;
|
||||
}
|
||||
else if(sscanf(addressString, "broadcast:%d", &port) == 1)
|
||||
{
|
||||
address->port = port;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
S32 nodeNum[6];
|
||||
S32 netNum[4];
|
||||
S32 count = dSscanf(addressString, "%2x%2x%2x%2x:%2x%2x%2x%2x%2x%2x:%d",
|
||||
&netNum[0], &netNum[1], &netNum[2], &netNum[3],
|
||||
&nodeNum[0], &nodeNum[1], &nodeNum[2], &nodeNum[3], &nodeNum[4], &nodeNum[5],
|
||||
&port);
|
||||
|
||||
if(count == 10)
|
||||
{
|
||||
port = defaultPort;
|
||||
count++;
|
||||
}
|
||||
if(count != 11)
|
||||
return false;
|
||||
|
||||
for(i = 0; i < 6; i++)
|
||||
address->nodeNum[i] = nodeNum[i];
|
||||
for(i = 0; i < 4; i++)
|
||||
address->netNum[i] = netNum[i];
|
||||
address->port = port;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Net::addressToString(const NetAddress *address, char addressString[256])
|
||||
{
|
||||
if(address->type == NetAddress::IPAddress)
|
||||
{
|
||||
sockaddr_in ipAddr;
|
||||
netToIPSocketAddress(address, &ipAddr);
|
||||
|
||||
if(ipAddr.sin_addr.s_addr == htonl(INADDR_BROADCAST))
|
||||
dSprintf(addressString, 256, "IP:Broadcast:%d", ntohs(ipAddr.sin_port));
|
||||
else
|
||||
dSprintf(addressString, 256, "IP:%s:%d", inet_ntoa(ipAddr.sin_addr),
|
||||
ntohs(ipAddr.sin_port));
|
||||
// dSprintf(addressString, 256, "IP:%d:%d", ipAddr.sin_addr.s_addr,
|
||||
// ntohs(ipAddr.sin_port));
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
dSprintf(addressString, 256, "IPX:%.2X%.2X%.2X%.2X:%.2X%.2X%.2X%.2X%.2X%.2X:%d",
|
||||
address->netNum[0], address->netNum[1], address->netNum[2], address->netNum[3],
|
||||
address->nodeNum[0], address->nodeNum[1], address->nodeNum[2], address->nodeNum[3], address->nodeNum[4], address->nodeNum[5],
|
||||
address->port);
|
||||
}
|
||||
}
|
||||
|
||||
Net::Error getLastError()
|
||||
{
|
||||
if (errno == EAGAIN)
|
||||
return Net::WouldBlock;
|
||||
return Net::UnknownError;
|
||||
}
|
||||
|
490
engine/platformX86UNIX/x86UNIXOGLVideo.cc
Executable file
490
engine/platformX86UNIX/x86UNIXOGLVideo.cc
Executable file
@ -0,0 +1,490 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
#include "console/console.h"
|
||||
#include "platform/event.h"
|
||||
#include "platform/gameInterface.h"
|
||||
|
||||
#include "platformX86UNIX/platformX86UNIX.h"
|
||||
#include "platformX86UNIX/platformGL.h"
|
||||
#include "platformX86UNIX/x86UNIXOGLVideo.h"
|
||||
#include "platformX86UNIX/x86UNIXState.h"
|
||||
|
||||
#include <SDL/SDL.h>
|
||||
#include <SDL/SDL_syswm.h>
|
||||
#include <SDL/SDL_version.h>
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool InitOpenGL()
|
||||
{
|
||||
DisplayDevice::init();
|
||||
|
||||
// Get the video settings from the prefs:
|
||||
const char* resString = Con::getVariable( "$pref::Video::resolution" );
|
||||
char* tempBuf = new char[dStrlen( resString ) + 1];
|
||||
dStrcpy( tempBuf, resString );
|
||||
char* temp = dStrtok( tempBuf, " x\0" );
|
||||
U32 width = ( temp ? dAtoi( temp ) : 800 );
|
||||
temp = dStrtok( NULL, " x\0" );
|
||||
U32 height = ( temp ? dAtoi( temp ) : 600 );
|
||||
temp = dStrtok( NULL, "\0" );
|
||||
U32 bpp = ( temp ? dAtoi( temp ) : 16 );
|
||||
delete [] tempBuf;
|
||||
|
||||
bool fullScreen = Con::getBoolVariable( "$pref::Video::fullScreen" );
|
||||
|
||||
// the only supported video device in unix is OpenGL
|
||||
if ( !Video::setDevice( "OpenGL", width, height, bpp, fullScreen ) )
|
||||
{
|
||||
Con::errorf("Unable to create default OpenGL mode: %d %d %d %d",
|
||||
width, height, bpp, fullScreen);
|
||||
|
||||
// if we can't create the default, attempt to create a "safe" window
|
||||
if ( !Video::setDevice( "OpenGL", 640, 480, 16, true ) )
|
||||
{
|
||||
DisplayErrorAlert("Could not find a compatible OpenGL display " \
|
||||
"resolution. Please check your driver configuration.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool OpenGLDevice::smCanSwitchBitDepth = false;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
OpenGLDevice::OpenGLDevice()
|
||||
{
|
||||
initDevice();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
OpenGLDevice::~OpenGLDevice()
|
||||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void OpenGLDevice::addResolution(S32 width, S32 height, bool check)
|
||||
{
|
||||
Point2I desktopSize = x86UNIXState->getDesktopSize();
|
||||
U32 desktopBpp = x86UNIXState->getDesktopBpp();
|
||||
|
||||
// don't allow any resolution under this size
|
||||
if (width < 640 || height < 480)
|
||||
return;
|
||||
|
||||
if (check)
|
||||
{
|
||||
// don't allow resolutions that exceed the current desktop size
|
||||
if (width > desktopSize.x || height > desktopSize.y)
|
||||
return;
|
||||
}
|
||||
|
||||
if (smCanSwitchBitDepth)
|
||||
{
|
||||
// add both 16 and 32 bit resolutions
|
||||
mResolutionList.push_back(Resolution(width, height, 16));
|
||||
mResolutionList.push_back(Resolution(width, height, 32));
|
||||
}
|
||||
else
|
||||
{
|
||||
// add just the desktop resolution
|
||||
mResolutionList.push_back(Resolution(width, height, desktopBpp));
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void OpenGLDevice::initDevice()
|
||||
{
|
||||
mDeviceName = "OpenGL";
|
||||
mFullScreenOnly = false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void OpenGLDevice::loadResolutions()
|
||||
{
|
||||
mResolutionList.clear();
|
||||
|
||||
// X cannot switch bit depths on the fly. In case this feature is
|
||||
// implemented someday, calling this function will let you take
|
||||
// advantage of it
|
||||
if (Con::getBoolVariable("$pref::Unix::CanSwitchBitDepth"))
|
||||
smCanSwitchBitDepth = true;
|
||||
|
||||
// add some default resolutions
|
||||
addResolution(640, 480);
|
||||
addResolution(800, 600);
|
||||
addResolution(1024, 768);
|
||||
addResolution(1152, 864);
|
||||
addResolution(1280, 1024);
|
||||
addResolution(1600, 1200);
|
||||
|
||||
// specifying full screen should give us the resolutions that the
|
||||
// X server allows
|
||||
SDL_Rect** modes = SDL_ListModes(NULL, SDL_FULLSCREEN);
|
||||
if (modes &&
|
||||
(modes != (SDL_Rect **)-1))
|
||||
{
|
||||
for (int i = 0; modes[i] != NULL; ++i)
|
||||
{
|
||||
// do we already have this mode?
|
||||
bool found = false;
|
||||
for (Vector<Resolution>::iterator iter = mResolutionList.begin();
|
||||
iter != mResolutionList.end();
|
||||
++iter)
|
||||
{
|
||||
if (iter->w == modes[i]->w && iter->h == modes[i]->h)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
// don't check these resolutions because they should be OK
|
||||
// (and checking might drop resolutions that are higher than the
|
||||
// current desktop bpp)
|
||||
addResolution(modes[i]->w, modes[i]->h, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool OpenGLDevice::activate( U32 width, U32 height, U32 bpp, bool fullScreen )
|
||||
{
|
||||
if (!setScreenMode(width, height, bpp, fullScreen))
|
||||
{
|
||||
Con::printf("Unable to set screen mode.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Output some driver info to the console
|
||||
const char* vendorString = (const char*) glGetString( GL_VENDOR );
|
||||
const char* rendererString = (const char*) glGetString( GL_RENDERER );
|
||||
const char* versionString = (const char*) glGetString( GL_VERSION );
|
||||
Con::printf( "OpenGL driver information:" );
|
||||
if ( vendorString )
|
||||
Con::printf( " Vendor: %s", vendorString );
|
||||
if ( rendererString )
|
||||
Con::printf( " Renderer: %s", rendererString );
|
||||
if ( versionString )
|
||||
Con::printf( " Version: %s", versionString );
|
||||
|
||||
GL_EXT_Init();
|
||||
|
||||
Con::setVariable( "$pref::Video::displayDevice", mDeviceName );
|
||||
|
||||
// Do this here because we now know about the extensions:
|
||||
if ( gGLState.suppSwapInterval )
|
||||
setVerticalSync(
|
||||
!Con::getBoolVariable( "$pref::Video::disableVerticalSync" ) );
|
||||
Con::setBoolVariable("$pref::OpenGL::allowTexGen", true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void OpenGLDevice::shutdown()
|
||||
{
|
||||
// Shutdown is deferred to Platform::shutdown()
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void PrintGLAttributes()
|
||||
{
|
||||
int doubleBuf;
|
||||
int bufferSize, depthSize, stencilSize;
|
||||
int red, green, blue, alpha;
|
||||
int aRed, aGreen, aBlue, aAlpha;
|
||||
|
||||
SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &doubleBuf);
|
||||
SDL_GL_GetAttribute(SDL_GL_BUFFER_SIZE, &bufferSize);
|
||||
SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &depthSize);
|
||||
SDL_GL_GetAttribute(SDL_GL_STENCIL_SIZE, &stencilSize);
|
||||
SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &red);
|
||||
SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &green);
|
||||
SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &blue);
|
||||
SDL_GL_GetAttribute(SDL_GL_ALPHA_SIZE, &alpha);
|
||||
SDL_GL_GetAttribute(SDL_GL_ACCUM_RED_SIZE, &aRed);
|
||||
SDL_GL_GetAttribute(SDL_GL_ACCUM_GREEN_SIZE, &aGreen);
|
||||
SDL_GL_GetAttribute(SDL_GL_ACCUM_BLUE_SIZE, &aBlue);
|
||||
SDL_GL_GetAttribute(SDL_GL_ACCUM_ALPHA_SIZE, &aAlpha);
|
||||
|
||||
Con::printf("OpenGL Attributes:");
|
||||
Con::printf(" DoubleBuffer: %d", doubleBuf);
|
||||
Con::printf(" BufferSize: %d, DepthSize: %d, StencilSize: %d",
|
||||
bufferSize, depthSize, stencilSize);
|
||||
Con::printf(" Red: %d, Green: %d, Blue: %d, Alpha: %d",
|
||||
red, green, blue, alpha);
|
||||
Con::printf(" Accum Red: %d, Green: %d, Blue: %d, Alpha: %d",
|
||||
aRed, aGreen, aBlue, aAlpha);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool OpenGLDevice::setScreenMode( U32 width, U32 height, U32 bpp,
|
||||
bool fullScreen, bool forceIt, bool repaint )
|
||||
{
|
||||
// load resolutions, this is done lazily so that we can check the setting
|
||||
// of smCanSwitchBitDepth, which may be overridden by console
|
||||
if (mResolutionList.size()==0)
|
||||
loadResolutions();
|
||||
|
||||
if (mResolutionList.size()==0)
|
||||
{
|
||||
Con::printf("No resolutions available!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (bpp == 0)
|
||||
{
|
||||
// bpp comes in as "0" when it is set to "Default"
|
||||
bpp = x86UNIXState->getDesktopBpp();
|
||||
}
|
||||
|
||||
if (height == 0 || width == 0)
|
||||
{
|
||||
// paranoia check. set it to the default to prevent crashing
|
||||
width = 800;
|
||||
height = 600;
|
||||
}
|
||||
|
||||
U32 desktopDepth = x86UNIXState->getDesktopBpp();
|
||||
// if we can't switch bit depths and the requested bpp is not equal to
|
||||
// the desktop bpp, set bpp to the desktop bpp
|
||||
if (!smCanSwitchBitDepth &&
|
||||
bpp != desktopDepth)
|
||||
{
|
||||
bpp = desktopDepth;
|
||||
}
|
||||
|
||||
bool IsInList = false;
|
||||
|
||||
Resolution NewResolution( width, height, bpp );
|
||||
|
||||
// See if the desired resolution is in the list
|
||||
if ( mResolutionList.size() )
|
||||
{
|
||||
for ( int i = 0; i < mResolutionList.size(); i++ )
|
||||
{
|
||||
if ( width == mResolutionList[i].w
|
||||
&& height == mResolutionList[i].h
|
||||
&& bpp == mResolutionList[i].bpp )
|
||||
{
|
||||
IsInList = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !IsInList )
|
||||
{
|
||||
Con::printf( "Selected resolution not available: %d %d %d",
|
||||
width, height, bpp);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AssertFatal( false, "No resolution list found!!" );
|
||||
}
|
||||
|
||||
// Here if we found a matching resolution in the list
|
||||
|
||||
bool needResurrect = false;
|
||||
if (x86UNIXState->windowCreated())
|
||||
{
|
||||
Con::printf( "Killing the texture manager..." );
|
||||
Game->textureKill();
|
||||
needResurrect = true;
|
||||
}
|
||||
|
||||
// Set the desired GL Attributes
|
||||
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
||||
// JMQ: NVIDIA 2802+ doesn't like this setting for stencil size
|
||||
// SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
|
||||
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0);
|
||||
SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE, 0);
|
||||
SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE, 0);
|
||||
SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE, 0);
|
||||
SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE, 0);
|
||||
// SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
|
||||
// SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
|
||||
// SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 6);
|
||||
// SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
|
||||
|
||||
U32 flags = SDL_OPENGL;
|
||||
if (fullScreen)
|
||||
flags |= SDL_FULLSCREEN;
|
||||
|
||||
Con::printf( "Setting screen mode to %dx%dx%d (%s)...", width, height,
|
||||
bpp, ( fullScreen ? "fs" : "w" ) );
|
||||
|
||||
// set the new video mode
|
||||
if (SDL_SetVideoMode(width, height, bpp, flags) == NULL)
|
||||
{
|
||||
Con::printf("Unable to set SDL Video Mode: %s", SDL_GetError());
|
||||
return false;
|
||||
}
|
||||
|
||||
PrintGLAttributes();
|
||||
|
||||
// clear screen here to prevent buffer garbage from being displayed when
|
||||
// video mode is switched
|
||||
glClearColor(0.0, 0.0, 0.0, 0.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
|
||||
if ( needResurrect )
|
||||
{
|
||||
// Reload the textures:
|
||||
Con::printf( "Resurrecting the texture manager..." );
|
||||
Game->textureResurrect();
|
||||
}
|
||||
|
||||
if ( gGLState.suppSwapInterval )
|
||||
setVerticalSync( !Con::getBoolVariable( "$pref::Video::disableVerticalSync" ) );
|
||||
|
||||
// reset the window in platform state
|
||||
SDL_SysWMinfo sysinfo;
|
||||
SDL_VERSION(&sysinfo.version);
|
||||
if (SDL_GetWMInfo(&sysinfo) == 0)
|
||||
{
|
||||
Con::printf("Unable to set SDL Video Mode: %s", SDL_GetError());
|
||||
return false;
|
||||
}
|
||||
x86UNIXState->setWindow(sysinfo.info.x11.window);
|
||||
|
||||
// set various other parameters
|
||||
x86UNIXState->setWindowCreated(true);
|
||||
smCurrentRes = NewResolution;
|
||||
Platform::setWindowSize ( width, height );
|
||||
smIsFullScreen = fullScreen;
|
||||
Con::setBoolVariable( "$pref::Video::fullScreen", smIsFullScreen );
|
||||
char tempBuf[15];
|
||||
dSprintf( tempBuf, sizeof( tempBuf ), "%d %d %d",
|
||||
smCurrentRes.w, smCurrentRes.h, smCurrentRes.bpp );
|
||||
Con::setVariable( "$pref::Video::resolution", tempBuf );
|
||||
|
||||
// post a TORQUE_SETVIDEOMODE user event
|
||||
SDL_Event event;
|
||||
event.type = SDL_USEREVENT;
|
||||
event.user.code = TORQUE_SETVIDEOMODE;
|
||||
event.user.data1 = NULL;
|
||||
event.user.data2 = NULL;
|
||||
SDL_PushEvent(&event);
|
||||
|
||||
// reset the caption
|
||||
SDL_WM_SetCaption(x86UNIXState->getWindowName(), NULL);
|
||||
|
||||
// repaint
|
||||
if ( repaint )
|
||||
Con::evaluate( "resetCanvas();" );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void OpenGLDevice::swapBuffers()
|
||||
{
|
||||
SDL_GL_SwapBuffers();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
const char* OpenGLDevice::getDriverInfo()
|
||||
{
|
||||
const char* vendorString = (const char*) glGetString( GL_VENDOR );
|
||||
const char* rendererString = (const char*) glGetString( GL_RENDERER );
|
||||
const char* versionString = (const char*) glGetString( GL_VERSION );
|
||||
const char* extensionsString = (const char*) glGetString( GL_EXTENSIONS );
|
||||
|
||||
U32 bufferLen = ( vendorString ? dStrlen( vendorString ) : 0 )
|
||||
+ ( rendererString ? dStrlen( rendererString ) : 0 )
|
||||
+ ( versionString ? dStrlen( versionString ) : 0 )
|
||||
+ ( extensionsString ? dStrlen( extensionsString ) : 0 )
|
||||
+ 4;
|
||||
|
||||
char* returnString = Con::getReturnBuffer( bufferLen );
|
||||
dSprintf( returnString, bufferLen, "%s\t%s\t%s\t%s",
|
||||
( vendorString ? vendorString : "" ),
|
||||
( rendererString ? rendererString : "" ),
|
||||
( versionString ? versionString : "" ),
|
||||
( extensionsString ? extensionsString : "" ) );
|
||||
|
||||
return( returnString );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool OpenGLDevice::getGammaCorrection(F32 &g)
|
||||
{
|
||||
U16 redtable[256];
|
||||
U16 greentable[256];
|
||||
U16 bluetable[256];
|
||||
|
||||
if (SDL_GetGammaRamp(redtable, greentable, bluetable) == -1)
|
||||
{
|
||||
Con::warnf("getGammaCorrection error: %s", SDL_GetError());
|
||||
return false;
|
||||
}
|
||||
|
||||
F32 csum = 0.0;
|
||||
U32 ccount = 0;
|
||||
|
||||
for (U16 i = 0; i < 256; ++i)
|
||||
{
|
||||
if (i != 0 && redtable[i] != 0 && redtable[i] != 65535)
|
||||
{
|
||||
F64 b = (F64) i/256.0;
|
||||
F64 a = (F64) redtable[i]/65535.0;
|
||||
F32 c = (F32) (mLog(a)/mLog(b));
|
||||
|
||||
csum += c;
|
||||
++ccount;
|
||||
}
|
||||
}
|
||||
g = csum/ccount;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool OpenGLDevice::setGammaCorrection(F32 g)
|
||||
{
|
||||
U16 redtable[256];
|
||||
U16 greentable[256];
|
||||
U16 bluetable[256];
|
||||
|
||||
for (U16 i = 0; i < 256; ++i)
|
||||
redtable[i] = static_cast<U16>(mPow((F32) i/256.0f, g) * 65535.0f);
|
||||
dMemcpy(greentable,redtable,256*sizeof(U16));
|
||||
dMemcpy(bluetable,redtable,256*sizeof(U16));
|
||||
|
||||
S32 ok = SDL_SetGammaRamp(redtable, greentable, bluetable);
|
||||
if (ok == -1)
|
||||
Con::warnf("Error setting gamma correction: %s", SDL_GetError());
|
||||
|
||||
return ok != -1;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool OpenGLDevice::setVerticalSync( bool on )
|
||||
{
|
||||
Con::printf("WARNING: OpenGLDevice::setVerticalSync is unimplemented %s %d\n", __FILE__, __LINE__);
|
||||
return false;
|
||||
#if 0
|
||||
if ( !gGLState.suppSwapInterval )
|
||||
return( false );
|
||||
|
||||
return( qwglSwapIntervalEXT( on ? 1 : 0 ) );
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
DisplayDevice* OpenGLDevice::create()
|
||||
{
|
||||
return new OpenGLDevice();
|
||||
}
|
43
engine/platformX86UNIX/x86UNIXOGLVideo.h
Executable file
43
engine/platformX86UNIX/x86UNIXOGLVideo.h
Executable file
@ -0,0 +1,43 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
#ifndef _X86UNIXOGLVIDEO_H_
|
||||
#define _X86UNIXOGLVIDEO_H_
|
||||
|
||||
#ifndef _PLATFORMVIDEO_H_
|
||||
#include "platform/platformVideo.h"
|
||||
#endif
|
||||
|
||||
class OpenGLDevice : public DisplayDevice
|
||||
{
|
||||
static bool smCanSwitchBitDepth;
|
||||
|
||||
bool mRestoreGamma;
|
||||
U16 mOriginalRamp[256*3];
|
||||
|
||||
void addResolution(S32 width, S32 height, bool check=true);
|
||||
|
||||
public:
|
||||
OpenGLDevice();
|
||||
virtual ~OpenGLDevice();
|
||||
|
||||
void initDevice();
|
||||
bool activate( U32 width, U32 height, U32 bpp, bool fullScreen );
|
||||
void shutdown();
|
||||
void destroy();
|
||||
bool setScreenMode( U32 width, U32 height, U32 bpp, bool fullScreen, bool forceIt = false, bool repaint = true );
|
||||
void swapBuffers();
|
||||
const char* getDriverInfo();
|
||||
bool getGammaCorrection(F32 &g);
|
||||
bool setGammaCorrection(F32 g);
|
||||
bool setVerticalSync( bool on );
|
||||
void loadResolutions();
|
||||
|
||||
static DisplayDevice* create();
|
||||
};
|
||||
|
||||
#endif // _H_X86UNIXOGLVIDEO
|
269
engine/platformX86UNIX/x86UNIXOpenAL.cc
Executable file
269
engine/platformX86UNIX/x86UNIXOpenAL.cc
Executable file
@ -0,0 +1,269 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
#include "platformX86UNIX/platformX86UNIX.h"
|
||||
#include "console/console.h"
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include <al/altypes.h>
|
||||
#include <al/alctypes.h>
|
||||
#define INITGUID
|
||||
#include <al/eaxtypes.h>
|
||||
|
||||
|
||||
// Define the OpenAL and Extension Stub functions
|
||||
#define AL_FUNCTION(fn_return, fn_name, fn_args, fn_value) fn_return stub_##fn_name fn_args{ fn_value }
|
||||
#include <al/al_func.h>
|
||||
#include <al/alc_func.h>
|
||||
#include <al/eax_func.h>
|
||||
#undef AL_FUNCTION
|
||||
|
||||
|
||||
// Declare the OpenAL and Extension Function pointers
|
||||
// And initialize them to the stub functions
|
||||
#define AL_FUNCTION(fn_return,fn_name,fn_args, fn_value) fn_return (*fn_name)fn_args = stub_##fn_name;
|
||||
#include <al/al_func.h>
|
||||
#include <al/alc_func.h>
|
||||
#include <al/eax_func.h>
|
||||
#undef AL_FUNCTION
|
||||
|
||||
// Declarations for the "emulated" functions (al functions that don't
|
||||
// exist in the loki openal implementation)
|
||||
ALboolean emu_alGetBoolean(ALenum param);
|
||||
ALint emu_alGetInteger(ALenum param);
|
||||
ALfloat emu_alGetFloat(ALenum param);
|
||||
ALdouble emu_alGetDouble(ALenum param);
|
||||
void emu_alListeneri( ALenum param, ALint value );
|
||||
void emu_alGetListener3f(ALenum pname,ALfloat *v1,ALfloat *v2,ALfloat *v3);
|
||||
ALCdevice* emu_alcGetContextsDevice(ALCcontext *context);
|
||||
|
||||
static void *dlHandle = NULL;
|
||||
static char* dlError = "no error";
|
||||
|
||||
/*! Get an "emulated" function address and bind it to the function pointer
|
||||
*/
|
||||
static bool bindEmulatedFunction(void *&fnAddress, const char *name)
|
||||
{
|
||||
fnAddress = NULL;
|
||||
|
||||
if (dStrcmp(name, "alGetBoolean")==0)
|
||||
fnAddress = (void*)&emu_alGetBoolean;
|
||||
else if (dStrcmp(name, "alGetInteger")==0)
|
||||
fnAddress = (void*)&emu_alGetInteger;
|
||||
else if (dStrcmp(name, "alGetFloat")==0)
|
||||
fnAddress = (void*)&emu_alGetFloat;
|
||||
else if (dStrcmp(name, "alGetDouble")==0)
|
||||
fnAddress = (void*)&emu_alGetDouble;
|
||||
else if (dStrcmp(name, "alListeneri")==0)
|
||||
fnAddress = (void*)&emu_alListeneri;
|
||||
else if (dStrcmp(name, "alGetListener3f")==0)
|
||||
fnAddress = (void*)&emu_alGetListener3f;
|
||||
else if (dStrcmp(name, "alcGetContextsDevice")==0)
|
||||
fnAddress = (void*)&emu_alcGetContextsDevice;
|
||||
|
||||
return fnAddress != NULL;
|
||||
}
|
||||
|
||||
/*! Get a function address from the OpenAL DLL and bind it to the
|
||||
* function pointer
|
||||
*/
|
||||
static bool bindFunction( void *&fnAddress, const char *name )
|
||||
{
|
||||
fnAddress = dlsym(dlHandle, name);
|
||||
if( !fnAddress )
|
||||
if (bindEmulatedFunction(fnAddress, name))
|
||||
Con::warnf(ConsoleLogEntry::General, " Missing OpenAL function '%s', using emulated function", name);
|
||||
else
|
||||
Con::errorf(ConsoleLogEntry::General, " Missing OpenAL function '%s'", name);
|
||||
return (fnAddress != NULL);
|
||||
}
|
||||
|
||||
/*! Get a function address for an OpenAL extension function and bind it
|
||||
* to it's function pointer
|
||||
*/
|
||||
static bool bindExtensionFunction( void *&fnAddress, const char *name )
|
||||
{
|
||||
fnAddress = alGetProcAddress( (ALubyte*)name );
|
||||
if( !fnAddress )
|
||||
Con::errorf(ConsoleLogEntry::General, " Missing OpenAL Extension function '%s'", name);
|
||||
return (fnAddress != NULL);
|
||||
}
|
||||
|
||||
/*! Bind the functions in the OpenAL DLL to the al interface functions
|
||||
*/
|
||||
static bool bindOpenALFunctions()
|
||||
{
|
||||
bool result = true;
|
||||
#define AL_FUNCTION(fn_return, fn_name, fn_args, fn_value) result &= bindFunction( *(void**)&fn_name, #fn_name);
|
||||
#include <al/al_func.h>
|
||||
#include <al/alc_func.h>
|
||||
#undef AL_FUNCTION
|
||||
return result;
|
||||
}
|
||||
|
||||
/*! Bind the stub functions to the al interface functions
|
||||
*/
|
||||
static void unbindOpenALFunctions()
|
||||
{
|
||||
#define AL_FUNCTION(fn_return, fn_name, fn_args, fn_value) fn_name = stub_##fn_name;
|
||||
#include <al/al_func.h>
|
||||
#include <al/alc_func.h>
|
||||
#include <al/eax_func.h>
|
||||
#undef AL_FUNCTION
|
||||
}
|
||||
|
||||
/*! Bind the EAX Extension functions to the EAX interface functions
|
||||
*/
|
||||
static bool bindEAXFunctions()
|
||||
{
|
||||
bool result = true;
|
||||
#define AL_FUNCTION(fn_return, fn_name, fn_args, fn_value) result &= bindExtensionFunction( *(void**)&fn_name, #fn_name);
|
||||
#include <al/eax_func.h>
|
||||
#undef AL_FUNCTION
|
||||
return result;
|
||||
}
|
||||
|
||||
// Definitions for the emulated functions
|
||||
ALboolean emu_alGetBoolean(ALenum param)
|
||||
{
|
||||
ALboolean alboolean;
|
||||
alGetBooleanv(param, &alboolean);
|
||||
return alboolean;
|
||||
}
|
||||
|
||||
ALint emu_alGetInteger(ALenum param)
|
||||
{
|
||||
ALint alint;
|
||||
alGetIntegerv(param, &alint);
|
||||
return alint;
|
||||
}
|
||||
|
||||
ALfloat emu_alGetFloat(ALenum param)
|
||||
{
|
||||
ALfloat alfloat;
|
||||
alGetFloatv(param, &alfloat);
|
||||
return alfloat;
|
||||
}
|
||||
|
||||
ALdouble emu_alGetDouble(ALenum param)
|
||||
{
|
||||
ALdouble aldouble;
|
||||
alGetDoublev(param, &aldouble);
|
||||
return aldouble;
|
||||
}
|
||||
|
||||
void emu_alGetListener3f(ALenum pname,ALfloat *v0,ALfloat *v1,ALfloat *v2)
|
||||
{
|
||||
ALfloat ptArray[10];
|
||||
ptArray[0] = *v0;
|
||||
ptArray[1] = *v1;
|
||||
ptArray[2] = *v2;
|
||||
alGetListenerfv(pname, ptArray);
|
||||
*v0 = ptArray[0];
|
||||
*v1 = ptArray[1];
|
||||
*v2 = ptArray[2];
|
||||
}
|
||||
|
||||
void emu_alListeneri( ALenum param, ALint value )
|
||||
{
|
||||
alListenerf(param, static_cast<ALfloat>(value));
|
||||
}
|
||||
|
||||
ALCdevice* emu_alcGetContextsDevice(ALCcontext *context)
|
||||
{
|
||||
// this function isn't emulated
|
||||
AssertFatal(false, "alcGetContextsDevice is not available");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
namespace Audio
|
||||
{
|
||||
|
||||
/*! Shutdown and Unload the OpenAL DLL
|
||||
*/
|
||||
void OpenALDLLShutdown()
|
||||
{
|
||||
if (dlHandle != NULL)
|
||||
{
|
||||
dlclose(dlHandle);
|
||||
// FreeBSD didn't like that const dlerror() was returning.
|
||||
if ((dlError = (char *)dlerror()) != NULL)
|
||||
Con::errorf(ConsoleLogEntry::General, " Error unloading OpenAL Library: %s", dlError);
|
||||
}
|
||||
dlHandle = NULL;
|
||||
|
||||
unbindOpenALFunctions();
|
||||
}
|
||||
|
||||
/*! Dynamically Loads the OpenAL DLL if present and binds all the functions.
|
||||
* If there is no DLL or an unexpected error occurs binding functions the
|
||||
* stub functions are automatically bound.
|
||||
*/
|
||||
bool OpenALDLLInit()
|
||||
{
|
||||
OpenALDLLShutdown();
|
||||
|
||||
const char* libName = "libopenal.so";
|
||||
|
||||
// these are relative to the current working directory
|
||||
const char* searchPath[] = {
|
||||
"lib",
|
||||
"tplib", // superceeded by "lib", here for backass compatibility
|
||||
"", // i.e.: current working directory
|
||||
NULL // this must be last
|
||||
};
|
||||
|
||||
char openalPath[4096];
|
||||
for (int i = 0; searchPath[i] != NULL; ++i)
|
||||
{
|
||||
dSprintf(openalPath, sizeof(openalPath), "%s/%s/%s",
|
||||
Platform::getWorkingDirectory(),
|
||||
searchPath[i],
|
||||
libName);
|
||||
|
||||
Con::printf(" Searching for OpenAl at location : %s", openalPath);
|
||||
dlHandle = dlopen(openalPath, RTLD_NOW);
|
||||
if (dlHandle != NULL)
|
||||
{
|
||||
// found it
|
||||
Con::printf(" Loading OpenAL: %s", openalPath);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (dlHandle == NULL)
|
||||
{
|
||||
// couldn't find it in our searchPath, try the system path
|
||||
dlHandle = dlopen(libName, RTLD_NOW);
|
||||
if (dlHandle != NULL)
|
||||
Con::printf(" Loading OpenAL from system (dlopen) path");
|
||||
}
|
||||
|
||||
if (dlHandle != NULL)
|
||||
{
|
||||
// if the DLL loaded bind the OpenAL function pointers
|
||||
if(bindOpenALFunctions())
|
||||
{
|
||||
// if EAX is available bind it's function pointers
|
||||
if (alIsExtensionPresent((ALubyte*)"EAX" ))
|
||||
bindEAXFunctions();
|
||||
return(true);
|
||||
}
|
||||
|
||||
// an error occured, shutdown
|
||||
OpenALDLLShutdown();
|
||||
}
|
||||
else
|
||||
{
|
||||
Con::errorf(ConsoleLogEntry::General, " Error loading OpenAL Library: %s", dlerror());
|
||||
}
|
||||
return(false);
|
||||
}
|
||||
|
||||
} // end namespace Audio
|
||||
|
192
engine/platformX86UNIX/x86UNIXProcessControl.cc
Executable file
192
engine/platformX86UNIX/x86UNIXProcessControl.cc
Executable file
@ -0,0 +1,192 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
#include "platformX86UNIX/platformX86UNIX.h"
|
||||
#include "platformX86UNIX/x86UNIXState.h"
|
||||
#include "platformX86UNIX/x86UNIXStdConsole.h"
|
||||
#include "platformX86UNIX/x86UNIXMutex.h"
|
||||
#include "platform/gameInterface.h"
|
||||
#include "platform/platformVideo.h"
|
||||
#include "platform/platformInput.h"
|
||||
#include "console/console.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
|
||||
#ifndef DEDICATED
|
||||
#include <SDL/SDL.h>
|
||||
#endif
|
||||
|
||||
extern void SendQuitEvent();
|
||||
|
||||
ProcessMutex pMutex;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// This is a mainly a debugging function for intercepting a nonzero exit code
|
||||
// and generating a core dump for a stack trace.
|
||||
// Need an S64 here because postQuitMessage uses a U32, and
|
||||
// forceshutdown uses an S32. So S64 is needed to
|
||||
// accomodate them both
|
||||
static void CheckExitCode(S64 exitCode)
|
||||
{
|
||||
if (exitCode != 0)
|
||||
{
|
||||
Con::errorf(ConsoleLogEntry::General,
|
||||
"Nonzero exit code: %d, triggering SIGSEGV for core dump",
|
||||
exitCode);
|
||||
kill(getpid(), SIGSEGV);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
static void SignalHandler(int sigtype)
|
||||
{
|
||||
if (sigtype == SIGSEGV || sigtype == SIGTRAP)
|
||||
{
|
||||
signal(SIGSEGV, SIG_DFL);
|
||||
signal(SIGTRAP, SIG_DFL);
|
||||
// restore the signal handling to default so that we don't get into
|
||||
// a crash loop with ImmediateShutdown
|
||||
ImmediateShutdown(-sigtype, sigtype);
|
||||
}
|
||||
else
|
||||
{
|
||||
signal(sigtype, SIG_DFL);
|
||||
dPrintf("Unknown signal caught by SignalHandler: %d\n", sigtype);
|
||||
dFflushStdout();
|
||||
// exit to be safe
|
||||
ImmediateShutdown(1);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void Cleanup(bool minimal)
|
||||
{
|
||||
if (!minimal)
|
||||
{
|
||||
Video::destroy();
|
||||
Input::destroy();
|
||||
}
|
||||
|
||||
StdConsole::destroy();
|
||||
#ifndef DEDICATED
|
||||
GLLoader::OpenGLShutdown();
|
||||
SDL_Quit();
|
||||
#endif
|
||||
// Display* display = x86UNIXState->GetDisplayPointer();
|
||||
// if (display != NULL)
|
||||
// XCloseDisplay(display);
|
||||
pMutex.release();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void ImmediateShutdown(S32 exitCode, S32 signalNum)
|
||||
{
|
||||
bool segfault = signalNum > 0;
|
||||
|
||||
Cleanup(segfault);
|
||||
|
||||
if (!segfault)
|
||||
{
|
||||
dPrintf("Exiting\n");
|
||||
// exit (doesn't call destructors)
|
||||
_exit(exitCode);
|
||||
}
|
||||
else
|
||||
{
|
||||
// there is a problem in kernel 2.4.17 which causes a hang when a segfault
|
||||
// occurs. also subsequent runs of "ps" will hang and the machine has to be
|
||||
// hard reset to clear up the problem
|
||||
// JMQ: this bug appears to be fixed in 2.4.18
|
||||
//#define KERNEL_2_4_WORKAROUND
|
||||
#ifdef KERNEL_2_4_WORKAROUND
|
||||
dPrintf("Segmentation Fault (Exiting without core dump due to #define KERNEL_2_4_WORKAROUND)\n");
|
||||
dFflushStdout();
|
||||
_exit(exitCode);
|
||||
#else
|
||||
// kill with signal
|
||||
kill(getpid(), signalNum);
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void ProcessControlInit()
|
||||
{
|
||||
// JMQ: ignore IO signals background read/write terminal (so that we don't
|
||||
// get suspended in daemon mode)
|
||||
signal(SIGTTIN, SIG_IGN);
|
||||
signal(SIGTTOU, SIG_IGN);
|
||||
|
||||
// we're not interested in the exit status of child processes, so this
|
||||
// prevents zombies from accumulating.
|
||||
#if defined(__FreeBSD__)
|
||||
signal(SIGCHLD, SIG_IGN);
|
||||
#else
|
||||
signal(SIGCLD, SIG_IGN);
|
||||
#endif
|
||||
|
||||
// install signal handler for SIGSEGV, so that we can attempt
|
||||
// clean shutdown
|
||||
signal(SIGSEGV, &SignalHandler);
|
||||
signal(SIGTRAP, &SignalHandler);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool AcquireProcessMutex(const char *mutexName)
|
||||
{
|
||||
return pMutex.acquire(mutexName);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void Platform::postQuitMessage(const U32 in_quitVal)
|
||||
{
|
||||
// if we have a window send a quit event, otherwise just force shutdown
|
||||
#ifndef DEDICATED
|
||||
if (x86UNIXState->windowCreated())
|
||||
{
|
||||
CheckExitCode(in_quitVal);
|
||||
SendQuitEvent();
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
forceShutdown(in_quitVal);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void Platform::debugBreak()
|
||||
{
|
||||
// in windows, "Calling DebugBreak causes the program to display
|
||||
// a dialog box as if it had crashed." So we segfault.
|
||||
Con::errorf(ConsoleLogEntry::General,
|
||||
"Platform::debugBreak: triggering SIGSEGV for core dump");
|
||||
//kill(getpid(), SIGSEGV);
|
||||
kill(getpid(), SIGTRAP);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void Platform::forceShutdown(S32 returnValue)
|
||||
{
|
||||
CheckExitCode(returnValue);
|
||||
|
||||
// if a dedicated server is running, turn it off
|
||||
if (x86UNIXState->isDedicated() && Game->isRunning())
|
||||
Game->setRunning(false);
|
||||
else
|
||||
ImmediateShutdown(returnValue);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// testing function
|
||||
ConsoleFunction(debug_debugbreak, void, 1, 1, "debug_debugbreak()")
|
||||
{
|
||||
Platform::debugBreak();
|
||||
}
|
439
engine/platformX86UNIX/x86UNIXRedbook.cc
Executable file
439
engine/platformX86UNIX/x86UNIXRedbook.cc
Executable file
@ -0,0 +1,439 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
#include "console/console.h"
|
||||
#include "platformX86UNIX/platformX86UNIX.h"
|
||||
#include "platform/platformRedBook.h"
|
||||
|
||||
#if defined(__linux__)
|
||||
#include <linux/cdrom.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#include <SDL/SDL.h>
|
||||
|
||||
class UnixRedBookDevice : public RedBookDevice
|
||||
{
|
||||
#if !defined(__FreeBSD__)
|
||||
private:
|
||||
S32 mDeviceId;
|
||||
SDL_CD *mCD;
|
||||
cdrom_volctrl mOriginalVolume;
|
||||
bool mVolumeInitialized;
|
||||
#endif
|
||||
bool mPlaying;
|
||||
|
||||
void openVolume();
|
||||
void closeVolume();
|
||||
void setLastError(const char *);
|
||||
|
||||
public:
|
||||
UnixRedBookDevice();
|
||||
~UnixRedBookDevice();
|
||||
|
||||
bool open();
|
||||
bool close();
|
||||
bool play(U32);
|
||||
bool stop();
|
||||
bool getTrackCount(U32 *);
|
||||
bool getVolume(F32 *);
|
||||
bool setVolume(F32);
|
||||
|
||||
bool isPlaying() { return mPlaying; }
|
||||
bool updateStatus();
|
||||
void setDeviceInfo(S32 deviceId, const char *deviceName);
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// Class: UnixRedBookDevice
|
||||
//-------------------------------------------------------------------------------
|
||||
UnixRedBookDevice::UnixRedBookDevice()
|
||||
{
|
||||
#if !defined(__FreeBSD__)
|
||||
mVolumeInitialized = false;
|
||||
mDeviceId = -1;
|
||||
mDeviceName = NULL;
|
||||
mCD = NULL;
|
||||
mPlaying = false;
|
||||
#endif // !defined(__FreeBSD__)
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
UnixRedBookDevice::~UnixRedBookDevice()
|
||||
{
|
||||
#if !defined(__FreeBSD__)
|
||||
close();
|
||||
#endif // !defined(__FreeBSD__)
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool UnixRedBookDevice::updateStatus()
|
||||
{
|
||||
#if !defined(__FreeBSD__)
|
||||
AssertFatal(mCD, "mCD is NULL");
|
||||
|
||||
CDstatus status = SDL_CDStatus(mCD);
|
||||
if (status == CD_ERROR)
|
||||
{
|
||||
setLastError("Error accessing device");
|
||||
return(false);
|
||||
}
|
||||
else if (status == CD_TRAYEMPTY)
|
||||
{
|
||||
setLastError("CD tray empty");
|
||||
return false;
|
||||
}
|
||||
|
||||
mPlaying = (status == CD_PLAYING);
|
||||
return true;
|
||||
#endif // !defined(__FreeBSD__)
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void UnixRedBookDevice::setDeviceInfo(S32 deviceId, const char *deviceName)
|
||||
{
|
||||
#if !defined(__FreeBSD__)
|
||||
mDeviceId = deviceId;
|
||||
mDeviceName = new char[dStrlen(deviceName) + 1];
|
||||
dStrcpy(mDeviceName, deviceName);
|
||||
#endif // !defined(__FreeBSD__)
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool UnixRedBookDevice::open()
|
||||
{
|
||||
#if !defined(__FreeBSD__)
|
||||
if(mAcquired)
|
||||
{
|
||||
setLastError("Device is already open.");
|
||||
return(false);
|
||||
}
|
||||
|
||||
// open the device
|
||||
mCD = SDL_CDOpen(mDeviceId);
|
||||
if (mCD == NULL)
|
||||
{
|
||||
setLastError(SDL_GetError());
|
||||
return false;
|
||||
}
|
||||
|
||||
mAcquired = true;
|
||||
|
||||
openVolume();
|
||||
setLastError("");
|
||||
return(true);
|
||||
#endif // !defined(__FreeBSD__)
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool UnixRedBookDevice::close()
|
||||
{
|
||||
#if !defined(__FreeBSD__)
|
||||
if(!mAcquired)
|
||||
{
|
||||
setLastError("Device has not been acquired");
|
||||
return(false);
|
||||
}
|
||||
|
||||
stop();
|
||||
closeVolume();
|
||||
|
||||
if (mCD != NULL)
|
||||
{
|
||||
SDL_CDClose(mCD);
|
||||
mCD = NULL;
|
||||
}
|
||||
|
||||
mAcquired = false;
|
||||
setLastError("");
|
||||
return(true);
|
||||
#endif // !defined(__FreeBSD__)
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool UnixRedBookDevice::play(U32 track)
|
||||
{
|
||||
#if !defined(__FreeBSD__)
|
||||
if(!mAcquired)
|
||||
{
|
||||
setLastError("Device has not been acquired");
|
||||
return(false);
|
||||
}
|
||||
|
||||
U32 numTracks;
|
||||
if(!getTrackCount(&numTracks))
|
||||
return(false);
|
||||
|
||||
if(track >= numTracks)
|
||||
{
|
||||
setLastError("Track index is out of range");
|
||||
return(false);
|
||||
}
|
||||
|
||||
if (!updateStatus())
|
||||
return false;
|
||||
|
||||
AssertFatal(mCD, "mCD is NULL");
|
||||
if (SDL_CDPlayTracks(mCD, track, 0, 1, 0) == -1)
|
||||
{
|
||||
setLastError(SDL_GetError());
|
||||
return false;
|
||||
}
|
||||
|
||||
mPlaying = true;
|
||||
|
||||
setLastError("");
|
||||
return(true);
|
||||
#endif // !defined(__FreeBSD__)
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool UnixRedBookDevice::stop()
|
||||
{
|
||||
#if !defined(__FreeBSD__)
|
||||
if(!mAcquired)
|
||||
{
|
||||
setLastError("Device has not been acquired");
|
||||
return(false);
|
||||
}
|
||||
|
||||
AssertFatal(mCD, "mCD is NULL");
|
||||
|
||||
if (SDL_CDStop(mCD) == -1)
|
||||
{
|
||||
setLastError(SDL_GetError());
|
||||
return(false);
|
||||
}
|
||||
|
||||
mPlaying = false;
|
||||
|
||||
setLastError("");
|
||||
return(true);
|
||||
#endif // !defined(__FreeBSD__)
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool UnixRedBookDevice::getTrackCount(U32 * numTracks)
|
||||
{
|
||||
#if !defined(__FreeBSD__)
|
||||
if(!mAcquired)
|
||||
{
|
||||
setLastError("Device has not been acquired");
|
||||
return(false);
|
||||
}
|
||||
|
||||
if (!updateStatus())
|
||||
return false;
|
||||
|
||||
AssertFatal(mCD, "mCD is NULL");
|
||||
*numTracks = mCD->numtracks;
|
||||
|
||||
return(true);
|
||||
#endif // !defined(__FreeBSD__)
|
||||
}
|
||||
|
||||
template <class Type>
|
||||
static inline Type max(Type v1, Type v2)
|
||||
{
|
||||
#if !defined(__FreeBSD__)
|
||||
if (v1 <= v2)
|
||||
return v2;
|
||||
else
|
||||
return v1;
|
||||
#endif // !defined(__FreeBSD__)
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
bool UnixRedBookDevice::getVolume(F32 * volume)
|
||||
{
|
||||
#if !defined(__FreeBSD__)
|
||||
if(!mAcquired)
|
||||
{
|
||||
setLastError("Device has not been acquired");
|
||||
return(false);
|
||||
}
|
||||
|
||||
if(!mVolumeInitialized)
|
||||
{
|
||||
setLastError("Volume failed to initialize");
|
||||
return(false);
|
||||
}
|
||||
|
||||
#if defined(__linux__)
|
||||
AssertFatal(mCD, "mCD is NULL");
|
||||
|
||||
setLastError("");
|
||||
cdrom_volctrl sysvol;
|
||||
if (ioctl(mCD->id, CDROMVOLREAD, &sysvol) == -1)
|
||||
{
|
||||
setLastError(strerror(errno));
|
||||
return(false);
|
||||
}
|
||||
U8 maxVol = max(sysvol.channel0, sysvol.channel1);
|
||||
// JMQTODO: support different left/right channel volumes?
|
||||
*volume = static_cast<F32>(maxVol) / 255.f;
|
||||
return true;
|
||||
#else
|
||||
return(false);
|
||||
#endif
|
||||
#endif // !defined(__FreeBSD__)
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool UnixRedBookDevice::setVolume(F32 volume)
|
||||
{
|
||||
#if !defined(__FreeBSD__)
|
||||
if(!mAcquired)
|
||||
{
|
||||
setLastError("Device has not been acquired");
|
||||
return(false);
|
||||
}
|
||||
|
||||
if(!mVolumeInitialized)
|
||||
{
|
||||
setLastError("Volume failed to initialize");
|
||||
return(false);
|
||||
}
|
||||
|
||||
#if defined(__linux__)
|
||||
AssertFatal(mCD, "mCD is NULL");
|
||||
|
||||
setLastError("");
|
||||
cdrom_volctrl sysvol;
|
||||
volume = volume * 255.f;
|
||||
if (volume > 255)
|
||||
volume = 255;
|
||||
if (volume < 0)
|
||||
volume = 0;
|
||||
sysvol.channel0 = sysvol.channel1 = static_cast<__u8>(volume);
|
||||
if (ioctl(mCD->id, CDROMVOLCTRL, &sysvol) == -1)
|
||||
{
|
||||
setLastError(strerror(errno));
|
||||
return(false);
|
||||
}
|
||||
return true;
|
||||
#else
|
||||
return(false);
|
||||
#endif
|
||||
#endif // !defined(__FreeBSD__)
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void UnixRedBookDevice::openVolume()
|
||||
{
|
||||
#if !defined(__FreeBSD__)
|
||||
// Its unforunate that we have to do it this way, but SDL does not currently
|
||||
// support setting CD audio volume
|
||||
#if defined(__linux__)
|
||||
AssertFatal(mCD, "mCD is NULL");
|
||||
|
||||
setLastError("");
|
||||
|
||||
if (ioctl(mCD->id, CDROMVOLREAD, &mOriginalVolume) == -1)
|
||||
{
|
||||
setLastError(strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
mVolumeInitialized = true;
|
||||
#else
|
||||
setLastError("Volume failed to initialize");
|
||||
#endif
|
||||
#endif // !defined(__FreeBSD__)
|
||||
}
|
||||
|
||||
void UnixRedBookDevice::closeVolume()
|
||||
{
|
||||
#if !defined(__FreeBSD__)
|
||||
if(!mVolumeInitialized)
|
||||
return;
|
||||
|
||||
#if defined(__linux__)
|
||||
AssertFatal(mCD, "mCD is NULL");
|
||||
|
||||
setLastError("");
|
||||
|
||||
if (ioctl(mCD->id, CDROMVOLCTRL, &mOriginalVolume) == -1)
|
||||
{
|
||||
setLastError(strerror(errno));
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
mVolumeInitialized = false;
|
||||
#endif // !defined(__FreeBSD__)
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void UnixRedBookDevice::setLastError(const char * error)
|
||||
{
|
||||
#if !defined(__FreeBSD__)
|
||||
RedBook::setLastError(error);
|
||||
#endif // !defined(__FreeBSD__)
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void InstallRedBookDevices()
|
||||
{
|
||||
#if !defined(__FreeBSD__)
|
||||
Con::printf("CD Audio Init:");
|
||||
if (SDL_InitSubSystem(SDL_INIT_CDROM) == -1)
|
||||
{
|
||||
Con::printf(" Unable to initialize CD Audio: %s", SDL_GetError());
|
||||
return;
|
||||
}
|
||||
|
||||
S32 numDrives = SDL_CDNumDrives();
|
||||
if (numDrives == 0)
|
||||
{
|
||||
Con::printf(" No drives found.");
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < numDrives; ++i)
|
||||
{
|
||||
const char * deviceName = SDL_CDName(i);
|
||||
Con::printf(" Installing CD Audio device: %s", deviceName);
|
||||
|
||||
UnixRedBookDevice * device = new UnixRedBookDevice;
|
||||
device->setDeviceInfo(i, deviceName);
|
||||
RedBook::installDevice(device);
|
||||
}
|
||||
|
||||
Con::printf(" ");
|
||||
#endif // !defined(__FreeBSD__)
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void PollRedbookDevices()
|
||||
{
|
||||
#if !defined(__FreeBSD__)
|
||||
UnixRedBookDevice *device = dynamic_cast<UnixRedBookDevice*>(RedBook::getCurrentDevice());
|
||||
|
||||
if (device == NULL || !device->isPlaying())
|
||||
return;
|
||||
|
||||
static const U32 PollDelay = 1000;
|
||||
|
||||
static U32 lastPollTime = 0;
|
||||
U32 curTime = Platform::getVirtualMilliseconds();
|
||||
|
||||
if (lastPollTime != 0 &&
|
||||
(curTime - lastPollTime) < PollDelay)
|
||||
return;
|
||||
|
||||
lastPollTime = curTime;
|
||||
|
||||
if (device->isPlaying())
|
||||
{
|
||||
device->updateStatus();
|
||||
if (!device->isPlaying())
|
||||
RedBook::handleCallback(RedBook::PlayFinished);
|
||||
}
|
||||
#endif // !defined(__FreeBSD__)
|
||||
}
|
93
engine/platformX86UNIX/x86UNIXSemaphore.cc
Executable file
93
engine/platformX86UNIX/x86UNIXSemaphore.cc
Executable file
@ -0,0 +1,93 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
#include "platformX86UNIX/platformX86UNIX.h"
|
||||
#include "platform/platformSemaphore.h"
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
//
|
||||
// Emulate the same behavior as the windows semaphore functions. We use
|
||||
// the phread functions to accomplish this as we are using them already.
|
||||
//
|
||||
struct sem_private {
|
||||
pthread_mutex_t mutex;
|
||||
pthread_cond_t con;
|
||||
int count;
|
||||
};
|
||||
|
||||
void * Semaphore::createSemaphore(U32 initialCount)
|
||||
{
|
||||
sem_private *semaphore = new sem_private;
|
||||
// Initialize the mutex
|
||||
if (pthread_mutex_init(&(semaphore->mutex), NULL))
|
||||
AssertFatal (false, "Semeaphore::createSemaphore: unable to create mutex");
|
||||
// Initialize the condition
|
||||
if (pthread_cond_init(&(semaphore->con), NULL))
|
||||
AssertFatal (false, "Semeaphore::createSemaphore: unable to create condition");
|
||||
semaphore->count = initialCount;
|
||||
return (semaphore);
|
||||
}
|
||||
|
||||
void Semaphore::destroySemaphore(void * semaphore)
|
||||
{
|
||||
AssertFatal (semaphore, "Semaphore::destroySemaphore: invalid semaphore.");
|
||||
sem_private *sem = static_cast<sem_private *>(semaphore);
|
||||
pthread_mutex_destroy(&(sem->mutex));
|
||||
pthread_cond_destroy(&(sem->con));
|
||||
delete sem;
|
||||
}
|
||||
|
||||
bool Semaphore::acquireSemaphore(void * semaphore, bool block)
|
||||
{
|
||||
AssertFatal (semaphore, "Semaphore::acqireSemaphore: invalid semaphore.");
|
||||
sem_private *sem = static_cast<sem_private *>(semaphore);
|
||||
if (block)
|
||||
{
|
||||
int result;
|
||||
pthread_mutex_lock(&(sem->mutex));
|
||||
while (sem->count <= 0)
|
||||
{
|
||||
result = pthread_cond_wait(&(sem->con), &(sem->mutex));
|
||||
if (result && errno != EINTR)
|
||||
break;
|
||||
}
|
||||
sem->count--;
|
||||
pthread_mutex_unlock(&(sem->mutex));
|
||||
return (true);
|
||||
}
|
||||
else
|
||||
{
|
||||
struct timespec tm;
|
||||
int result;
|
||||
result = pthread_mutex_trylock(&(sem->mutex));
|
||||
if (result == 0)
|
||||
{
|
||||
tm.tv_sec = 0;
|
||||
tm.tv_nsec = 0;
|
||||
while(sem->count <= 0)
|
||||
{
|
||||
result = pthread_cond_timedwait(&(sem->con), &(sem->mutex), &tm);
|
||||
if (result && (errno != EINTR))
|
||||
break;
|
||||
}
|
||||
sem->count--;
|
||||
pthread_mutex_unlock(&(sem->mutex));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void Semaphore::releaseSemaphore(void * semaphore)
|
||||
{
|
||||
AssertFatal(semaphore, "Semaphore::releaseSemaphore: invalid semaphore.");
|
||||
sem_private *sem = static_cast<sem_private *>(semaphore);
|
||||
pthread_mutex_lock(&(sem->mutex));
|
||||
sem->count++;
|
||||
pthread_mutex_unlock(&(sem->mutex));
|
||||
pthread_cond_broadcast(&(sem->con));
|
||||
}
|
260
engine/platformX86UNIX/x86UNIXState.h
Executable file
260
engine/platformX86UNIX/x86UNIXState.h
Executable file
@ -0,0 +1,260 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//
|
||||
// Initial revision: 12/13/01 Paul G. Allen, Random Logic Consulting
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
#include "math/mPoint.h"
|
||||
#include "platformX86UNIX/platformX86UNIX.h"
|
||||
#include "platformX86UNIX/platformGL.h"
|
||||
|
||||
#ifndef DEDICATED
|
||||
#include <X11/Xlib.h> // for Display, Window and other X mojo
|
||||
#else
|
||||
#define Display int
|
||||
#define Window int
|
||||
#define Screen int
|
||||
#endif
|
||||
|
||||
#include <libgen.h> // for basename
|
||||
|
||||
typedef void (*LockFunc_t)(void);
|
||||
|
||||
class DisplayPtrManager;
|
||||
|
||||
class x86UNIXPlatformState
|
||||
{
|
||||
friend class DisplayPtrManager;
|
||||
|
||||
private:
|
||||
Point2I mDesktopSize;
|
||||
Point2I mWindowSize;
|
||||
S32 mDesktopBpp;
|
||||
Display *mDisplay;
|
||||
Window mCurrentWindow;
|
||||
Screen *mScreenPointer;
|
||||
int mScreenNumber;
|
||||
char mWindowName[40];
|
||||
char mExePathName[4096];
|
||||
char mExeName[40];
|
||||
bool mWindowCreated;
|
||||
bool mWindowActive;
|
||||
bool mWindowLocked;
|
||||
bool mXWindowsRunning;
|
||||
bool mDedicated;
|
||||
bool mCDAudioEnabled;
|
||||
bool mDSleep;
|
||||
bool mUseRedirect;
|
||||
|
||||
// Access to the display* needs to be controlled because the SDL event
|
||||
// loop runs in a separate thread. If you need the display pointer,
|
||||
// use the DisplayPtrManager class. See the clipboard functions in
|
||||
// x86unixinput.cc for an example.
|
||||
Display *getDisplayPointer() { return mDisplay; }
|
||||
|
||||
public:
|
||||
U32 currentTime;
|
||||
|
||||
void setDisplayPointer( Display *displayPointer )
|
||||
{ mDisplay = displayPointer; }
|
||||
|
||||
void setScreenNumber( int newNumber ) { mScreenNumber = newNumber; }
|
||||
int getScreenNumber() { return mScreenNumber; }
|
||||
|
||||
void setScreenPointer( Screen *newScreenPointer )
|
||||
{ mScreenPointer = newScreenPointer; }
|
||||
Screen * getScreenPointer() { return mScreenPointer; }
|
||||
|
||||
// for compatibility, convert 24 bpp to 32
|
||||
void setDesktopBpp( S32 bpp )
|
||||
{
|
||||
if (bpp == 24)
|
||||
mDesktopBpp = 32;
|
||||
else
|
||||
mDesktopBpp = bpp;
|
||||
}
|
||||
S32 getDesktopBpp() { return mDesktopBpp; }
|
||||
|
||||
void setDesktopSize( S32 horizontal, S32 vertical )
|
||||
{ mDesktopSize.set( horizontal, vertical ); }
|
||||
Point2I getDesktopSize() { return mDesktopSize; }
|
||||
|
||||
void setWindow( Window newWindow ) { mCurrentWindow = newWindow; }
|
||||
Window getWindow() { return mCurrentWindow; }
|
||||
|
||||
void setWindowSize (S32 horizontal, S32 vertical )
|
||||
{ mWindowSize.set ( horizontal, vertical ); }
|
||||
void setWindowSize( Point2I size ) { mWindowSize = size; }
|
||||
Point2I& getWindowSize() { return ( mWindowSize ); }
|
||||
|
||||
void setWindowName (const char * windowName)
|
||||
{
|
||||
if (windowName == NULL)
|
||||
dStrncpy( mWindowName, "", sizeof( mWindowName ));
|
||||
else
|
||||
dStrncpy( mWindowName, windowName, sizeof( mWindowName ) );
|
||||
}
|
||||
const char * getWindowName() { return mWindowName; }
|
||||
|
||||
void setExePathName(const char* exePathName)
|
||||
{
|
||||
if (exePathName == NULL)
|
||||
dStrncpy(mExePathName, "", sizeof(mExePathName));
|
||||
else
|
||||
dStrncpy(mExePathName, exePathName, sizeof(mExePathName));
|
||||
|
||||
// set the base exe name field
|
||||
char tempBuf[2048];
|
||||
dStrncpy(tempBuf, mExePathName, 2048);
|
||||
dStrncpy(mExeName, basename(tempBuf), sizeof(mExeName));
|
||||
}
|
||||
const char * getExePathName() { return mExePathName; }
|
||||
const char * getExeName() { return mExeName; }
|
||||
|
||||
bool windowCreated() { return mWindowCreated; }
|
||||
bool windowActive() { return mWindowActive; }
|
||||
bool windowLocked() { return mWindowLocked; }
|
||||
void setWindowCreated(bool windowCreated)
|
||||
{ mWindowCreated = windowCreated; }
|
||||
void setWindowActive(bool windowActive)
|
||||
{ mWindowActive = windowActive; }
|
||||
void setWindowLocked(bool windowLocked)
|
||||
{ mWindowLocked = windowLocked; }
|
||||
|
||||
bool isXWindowsRunning() { return mXWindowsRunning; }
|
||||
void setXWindowsRunning(bool running) { mXWindowsRunning = running; }
|
||||
|
||||
bool isDedicated() { return mDedicated; }
|
||||
void setDedicated(bool dedicated) { mDedicated = dedicated; }
|
||||
|
||||
bool getCDAudioEnabled() { return mCDAudioEnabled; }
|
||||
void setCDAudioEnabled(bool enabled) { mCDAudioEnabled = enabled; }
|
||||
|
||||
bool getDSleep() { return mDSleep; }
|
||||
void setDSleep(bool enabled) { mDSleep = enabled; }
|
||||
|
||||
bool getUseRedirect() { return mUseRedirect; }
|
||||
void setUseRedirect(bool enabled) { mUseRedirect = enabled; }
|
||||
|
||||
x86UNIXPlatformState()
|
||||
{
|
||||
currentTime = 0;
|
||||
mDesktopBpp = 16;
|
||||
mDesktopSize.set( 0, 0 );
|
||||
mWindowSize.set( 800, 600 );
|
||||
setWindowName("Torque");
|
||||
setExePathName(NULL);
|
||||
mWindowCreated = mWindowActive = mWindowLocked = false;
|
||||
mXWindowsRunning = false;
|
||||
mDedicated = false;
|
||||
mCDAudioEnabled = false;
|
||||
mDSleep = false;
|
||||
#ifdef USE_FILE_REDIRECT
|
||||
mUseRedirect = true;
|
||||
#else
|
||||
mUseRedirect = false;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
extern x86UNIXPlatformState * x86UNIXState;
|
||||
|
||||
class DisplayPtrManager
|
||||
{
|
||||
// static interface
|
||||
private:
|
||||
static bool sgDisplayLocked;
|
||||
static LockFunc_t sgLockFunc;
|
||||
static LockFunc_t sgUnlockFunc;
|
||||
|
||||
static bool lockDisplay()
|
||||
{
|
||||
if (!sgDisplayLocked && sgLockFunc)
|
||||
{
|
||||
sgLockFunc();
|
||||
sgDisplayLocked = true;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
static void unlockDisplay()
|
||||
{
|
||||
if (sgDisplayLocked && sgUnlockFunc)
|
||||
{
|
||||
sgUnlockFunc();
|
||||
sgDisplayLocked = false;
|
||||
}
|
||||
}
|
||||
|
||||
//friend Display* x86UNIXPlatformState::getDisplayPointer();
|
||||
|
||||
public:
|
||||
static void setDisplayLockFunction(LockFunc_t lockFunc)
|
||||
{ sgLockFunc = lockFunc; }
|
||||
static void setDisplayUnlockFunction(LockFunc_t unlockFunc)
|
||||
{ sgUnlockFunc = unlockFunc; }
|
||||
|
||||
// nonstatic interface
|
||||
private:
|
||||
bool mAcquiredLock; // true if this instance acquired the display lock
|
||||
// (multiple instances of DisplayPtrManager can coexist, but only
|
||||
// the first to access the display pointer will be responsible for
|
||||
// acquiring and releasing the lock)
|
||||
bool mOpenedDisplay; // true if this instance created a display pointer
|
||||
// because the one in platform state was null.
|
||||
Display* mDisplay;
|
||||
|
||||
private:
|
||||
Display* openDisplay()
|
||||
{
|
||||
#ifndef DEDICATED
|
||||
mDisplay = XOpenDisplay(NULL);
|
||||
if (mDisplay != NULL)
|
||||
mOpenedDisplay = true;
|
||||
#endif
|
||||
return mDisplay;
|
||||
}
|
||||
|
||||
void closeDisplay()
|
||||
{
|
||||
if (mOpenedDisplay)
|
||||
{
|
||||
#ifndef DEDICATED
|
||||
XCloseDisplay(mDisplay);
|
||||
mDisplay = NULL;
|
||||
mOpenedDisplay = false;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
public:
|
||||
DisplayPtrManager()
|
||||
{
|
||||
mAcquiredLock = false;
|
||||
mOpenedDisplay = false;
|
||||
mDisplay = NULL;
|
||||
}
|
||||
|
||||
~DisplayPtrManager()
|
||||
{
|
||||
if (mAcquiredLock)
|
||||
{
|
||||
DisplayPtrManager::unlockDisplay();
|
||||
mAcquiredLock = false;
|
||||
}
|
||||
closeDisplay();
|
||||
}
|
||||
|
||||
Display* getDisplayPointer()
|
||||
{
|
||||
Display* display = x86UNIXState->getDisplayPointer();
|
||||
if (display == NULL)
|
||||
return openDisplay();
|
||||
|
||||
mAcquiredLock = DisplayPtrManager::lockDisplay();
|
||||
return display;
|
||||
}
|
||||
};
|
59
engine/platformX86UNIX/x86UNIXStdConsole.h
Executable file
59
engine/platformX86UNIX/x86UNIXStdConsole.h
Executable file
@ -0,0 +1,59 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
#ifndef _X86UNIXSTDCONSOLE_H_
|
||||
#define _X86UNIXSTDCONSOLE_H_
|
||||
|
||||
#define MAX_CMDS 10
|
||||
#ifndef _CONSOLE_H_
|
||||
#include "console/console.h"
|
||||
#endif
|
||||
#ifndef _EVENT_H_
|
||||
#include "platform/event.h"
|
||||
#endif
|
||||
|
||||
#include <termios.h>
|
||||
|
||||
class StdConsole
|
||||
{
|
||||
bool stdConsoleEnabled;
|
||||
// true if we're running in the background
|
||||
bool inBackground;
|
||||
|
||||
int stdOut;
|
||||
int stdIn;
|
||||
int stdErr;
|
||||
ConsoleEvent postEvent;
|
||||
char inbuf[512];
|
||||
S32 inpos;
|
||||
bool lineOutput;
|
||||
char curTabComplete[512];
|
||||
S32 tabCompleteStart;
|
||||
char rgCmds[MAX_CMDS][512];
|
||||
S32 iCmdIndex;
|
||||
|
||||
// this holds the original terminal state
|
||||
// before we messed with it
|
||||
struct termios *originalTermState;
|
||||
|
||||
void printf(const char *s, ...);
|
||||
|
||||
public:
|
||||
StdConsole();
|
||||
virtual ~StdConsole();
|
||||
void process();
|
||||
void enable(bool);
|
||||
void processConsoleLine(const char *consoleLine);
|
||||
static void create();
|
||||
static void destroy();
|
||||
static bool isEnabled();
|
||||
void resetTerminal();
|
||||
};
|
||||
|
||||
extern StdConsole *stdConsole;
|
||||
|
||||
#endif
|
408
engine/platformX86UNIX/x86UNIXStrings.cc
Executable file
408
engine/platformX86UNIX/x86UNIXStrings.cc
Executable file
@ -0,0 +1,408 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
#include "platformX86UNIX/platformX86UNIX.h"
|
||||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef HAS_VSSCANF
|
||||
# undef HAS_VSSCANF
|
||||
#endif
|
||||
|
||||
/* this routine turns a string to all uppercase - rjp */
|
||||
char *__strtoup(char *str)
|
||||
{
|
||||
char *newStr = str;
|
||||
if (newStr == NULL)
|
||||
return(NULL);
|
||||
while (*newStr)
|
||||
{
|
||||
*newStr = toupper(*newStr);
|
||||
*newStr++;
|
||||
}
|
||||
return(str);
|
||||
}
|
||||
/* this routine turns a string to all lowercase - rjp */
|
||||
char *__strtolwr(char *str)
|
||||
{
|
||||
char *newStr = str;
|
||||
if (newStr == NULL)
|
||||
return(NULL);
|
||||
while (*newStr)
|
||||
{
|
||||
*newStr = tolower(*newStr);
|
||||
*newStr++;
|
||||
}
|
||||
return(str);
|
||||
}
|
||||
|
||||
char *strtolwr(char* str)
|
||||
{
|
||||
return __strtolwr(str);
|
||||
}
|
||||
|
||||
char *stristr(char *szStringToBeSearched, const char *szSubstringToSearchFor)
|
||||
{
|
||||
char *pPos = NULL;
|
||||
char *szCopy1 = NULL;
|
||||
char *szCopy2 = NULL;
|
||||
|
||||
// verify parameters
|
||||
if ( szStringToBeSearched == NULL ||
|
||||
szSubstringToSearchFor == NULL )
|
||||
{
|
||||
return szStringToBeSearched;
|
||||
}
|
||||
|
||||
// empty substring - return input (consistent with strstr)
|
||||
if (strlen(szSubstringToSearchFor) == 0 ) {
|
||||
return szStringToBeSearched;
|
||||
}
|
||||
|
||||
szCopy1 = __strtolwr(strdup(szStringToBeSearched));
|
||||
szCopy2 = __strtolwr(strdup(szSubstringToSearchFor));
|
||||
|
||||
if ( szCopy1 == NULL || szCopy2 == NULL ) {
|
||||
// another option is to raise an exception here
|
||||
free((void*)szCopy1);
|
||||
free((void*)szCopy2);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pPos = strstr(szCopy1, szCopy2);
|
||||
|
||||
if ( pPos != NULL ) {
|
||||
// map to the original string
|
||||
pPos = szStringToBeSearched + (pPos - szCopy1);
|
||||
}
|
||||
|
||||
free((void*)szCopy1);
|
||||
free((void*)szCopy2);
|
||||
|
||||
return pPos;
|
||||
} // stristr(...)
|
||||
|
||||
char *dStrdup_r(const char *src, const char *fileName, U32 lineNumber)
|
||||
{
|
||||
char *buffer = (char *) dMalloc_r(dStrlen(src) + 1, fileName, lineNumber);
|
||||
dStrcpy(buffer, src);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
char* dStrcat(char *dst, const char *src)
|
||||
{
|
||||
return strcat(dst,src);
|
||||
}
|
||||
|
||||
char* dStrncat(char *dst, const char *src, U32 len)
|
||||
{
|
||||
return strncat(dst,src,len);
|
||||
}
|
||||
|
||||
// concatenates a list of src's onto the end of dst
|
||||
// the list of src's MUST be terminated by a NULL parameter
|
||||
// dStrcatl(dst, sizeof(dst), src1, src2, NULL);
|
||||
char* dStrcatl(char *dst, U32 dstSize, ...)
|
||||
{
|
||||
const char* src;
|
||||
char *p = dst;
|
||||
|
||||
AssertFatal(dstSize > 0, "dStrcatl: destination size is set zero");
|
||||
dstSize--; // leave room for string termination
|
||||
|
||||
// find end of dst
|
||||
while (dstSize && *p++)
|
||||
dstSize--;
|
||||
|
||||
va_list args;
|
||||
va_start(args, dstSize);
|
||||
|
||||
// concatenate each src to end of dst
|
||||
while ( (src = va_arg(args, const char*)) != NULL )
|
||||
while( dstSize && *src )
|
||||
{
|
||||
*p++ = *src++;
|
||||
dstSize--;
|
||||
}
|
||||
|
||||
va_end(args);
|
||||
|
||||
// make sure the string is terminated
|
||||
*p = 0;
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
|
||||
// copy a list of src's into dst
|
||||
// the list of src's MUST be terminated by a NULL parameter
|
||||
// dStrccpyl(dst, sizeof(dst), src1, src2, NULL);
|
||||
char* dStrcpyl(char *dst, U32 dstSize, ...)
|
||||
{
|
||||
const char* src;
|
||||
char *p = dst;
|
||||
|
||||
AssertFatal(dstSize > 0, "dStrcpyl: destination size is set zero");
|
||||
dstSize--; // leave room for string termination
|
||||
|
||||
va_list args;
|
||||
va_start(args, dstSize);
|
||||
|
||||
// concatenate each src to end of dst
|
||||
while ( (src = va_arg(args, const char*)) != NULL )
|
||||
while( dstSize && *src )
|
||||
{
|
||||
*p++ = *src++;
|
||||
dstSize--;
|
||||
}
|
||||
|
||||
va_end(args);
|
||||
|
||||
// make sure the string is terminated
|
||||
*p = 0;
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
|
||||
S32 dStrcmp(const char *str1, const char *str2)
|
||||
{
|
||||
return strcmp(str1, str2);
|
||||
}
|
||||
|
||||
S32 dStricmp(const char *str1, const char *str2)
|
||||
{
|
||||
return strcasecmp(str1, str2);
|
||||
}
|
||||
|
||||
S32 dStrncmp(const char *str1, const char *str2, U32 len)
|
||||
{
|
||||
return strncmp(str1, str2, len);
|
||||
}
|
||||
|
||||
S32 dStrnicmp(const char *str1, const char *str2, U32 len)
|
||||
{
|
||||
return strncasecmp(str1, str2, len);
|
||||
}
|
||||
|
||||
char* dStrcpy(char *dst, const char *src)
|
||||
{
|
||||
return strcpy(dst,src);
|
||||
}
|
||||
|
||||
char* dStrncpy(char *dst, const char *src, U32 len)
|
||||
{
|
||||
return strncpy(dst,src,len);
|
||||
}
|
||||
|
||||
U32 dStrlen(const char *str)
|
||||
{
|
||||
return strlen(str);
|
||||
}
|
||||
|
||||
|
||||
char* dStrupr(char *str)
|
||||
{
|
||||
#ifdef __MWERKS__ // metrowerks strupr is broken
|
||||
_strupr(str);
|
||||
return str;
|
||||
#else
|
||||
return __strtoup(str);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
char* dStrlwr(char *str)
|
||||
{
|
||||
return __strtolwr(str);
|
||||
}
|
||||
|
||||
|
||||
char* dStrchr(char *str, S32 c)
|
||||
{
|
||||
return strchr(str,c);
|
||||
}
|
||||
|
||||
|
||||
const char* dStrchr(const char *str, S32 c)
|
||||
{
|
||||
return strchr(str,c);
|
||||
}
|
||||
|
||||
|
||||
const char* dStrrchr(const char *str, S32 c)
|
||||
{
|
||||
return strrchr(str,c);
|
||||
}
|
||||
|
||||
char* dStrrchr(char *str, S32 c)
|
||||
{
|
||||
return strrchr(str,c);
|
||||
}
|
||||
|
||||
U32 dStrspn(const char *str, const char *set)
|
||||
{
|
||||
return(strspn(str, set));
|
||||
}
|
||||
|
||||
U32 dStrcspn(const char *str, const char *set)
|
||||
{
|
||||
return strcspn(str, set);
|
||||
}
|
||||
|
||||
|
||||
char* dStrstr(char *str1, char *str2)
|
||||
{
|
||||
return strstr(str1,str2);
|
||||
}
|
||||
|
||||
char* dStrstr(const char *str1, const char *str2)
|
||||
{
|
||||
return strstr(str1,str2);
|
||||
}
|
||||
|
||||
char* dStrtok(char *str, const char *sep)
|
||||
{
|
||||
return strtok(str, sep);
|
||||
}
|
||||
|
||||
|
||||
S32 dAtoi(const char *str)
|
||||
{
|
||||
return atoi(str);
|
||||
}
|
||||
|
||||
F32 dAtof(const char *str)
|
||||
{
|
||||
return atof(str);
|
||||
}
|
||||
|
||||
bool dAtob(const char *str)
|
||||
{
|
||||
return !dStricmp(str, "true") || dAtof(str);
|
||||
}
|
||||
|
||||
|
||||
bool dIsalnum(const char c)
|
||||
{
|
||||
return isalnum(c);
|
||||
}
|
||||
|
||||
bool dIsalpha(const char c)
|
||||
{
|
||||
return(isalpha(c));
|
||||
}
|
||||
|
||||
bool dIsspace(const char c)
|
||||
{
|
||||
return(isspace(c));
|
||||
}
|
||||
|
||||
bool dIsdigit(const char c)
|
||||
{
|
||||
return(isdigit(c));
|
||||
}
|
||||
|
||||
void dPrintf(const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vprintf(format, args);
|
||||
}
|
||||
|
||||
S32 dVprintf(const char *format, void *arglist)
|
||||
{
|
||||
S32 len = vprintf(format, (char*)arglist);
|
||||
return (len);
|
||||
}
|
||||
|
||||
S32 dSprintf(char *buffer, U32 bufferSize, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
|
||||
S32 len = vsnprintf(buffer, bufferSize, format, args);
|
||||
return (len);
|
||||
}
|
||||
|
||||
|
||||
S32 dVsprintf(char *buffer, U32 bufferSize, const char *format, void *arglist)
|
||||
{
|
||||
S32 len = vsnprintf(buffer, bufferSize, format, (char*)arglist);
|
||||
return (len);
|
||||
}
|
||||
|
||||
|
||||
S32 dSscanf(const char *buffer, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
#if defined(HAS_VSSCANF)
|
||||
va_start(args, format);
|
||||
return __vsscanf(buffer, format, args);
|
||||
#else
|
||||
va_start(args, format);
|
||||
|
||||
// Boy is this lame. We have to scan through the format string, and find out how many
|
||||
// arguments there are. We'll store them off as void*, and pass them to the sscanf
|
||||
// function through specialized calls. We're going to have to put a cap on the number of args that
|
||||
// can be passed, 8 for the moment. Sigh.
|
||||
static void* sVarArgs[20];
|
||||
U32 numArgs = 0;
|
||||
|
||||
for (const char* search = format; *search != '\0'; search++) {
|
||||
if (search[0] == '%' && search[1] != '%')
|
||||
numArgs++;
|
||||
}
|
||||
AssertFatal(numArgs <= 20, "Error, too many arguments to lame implementation of dSscanf. Fix implmentation");
|
||||
|
||||
// Ok, we have the number of arguments...
|
||||
for (U32 i = 0; i < numArgs; i++)
|
||||
sVarArgs[i] = va_arg(args, void*);
|
||||
va_end(args);
|
||||
|
||||
switch (numArgs) {
|
||||
case 0: return 0;
|
||||
case 1: return sscanf(buffer, format, sVarArgs[0]);
|
||||
case 2: return sscanf(buffer, format, sVarArgs[0], sVarArgs[1]);
|
||||
case 3: return sscanf(buffer, format, sVarArgs[0], sVarArgs[1], sVarArgs[2]);
|
||||
case 4: return sscanf(buffer, format, sVarArgs[0], sVarArgs[1], sVarArgs[2], sVarArgs[3]);
|
||||
case 5: return sscanf(buffer, format, sVarArgs[0], sVarArgs[1], sVarArgs[2], sVarArgs[3], sVarArgs[4]);
|
||||
case 6: return sscanf(buffer, format, sVarArgs[0], sVarArgs[1], sVarArgs[2], sVarArgs[3], sVarArgs[4], sVarArgs[5]);
|
||||
case 7: return sscanf(buffer, format, sVarArgs[0], sVarArgs[1], sVarArgs[2], sVarArgs[3], sVarArgs[4], sVarArgs[5], sVarArgs[6]);
|
||||
case 8: return sscanf(buffer, format, sVarArgs[0], sVarArgs[1], sVarArgs[2], sVarArgs[3], sVarArgs[4], sVarArgs[5], sVarArgs[6], sVarArgs[7]);
|
||||
case 9: return sscanf(buffer, format, sVarArgs[0], sVarArgs[1], sVarArgs[2], sVarArgs[3], sVarArgs[4], sVarArgs[5], sVarArgs[6], sVarArgs[7], sVarArgs[8]);
|
||||
case 10: return sscanf(buffer, format, sVarArgs[0], sVarArgs[1], sVarArgs[2], sVarArgs[3], sVarArgs[4], sVarArgs[5], sVarArgs[6], sVarArgs[7], sVarArgs[8], sVarArgs[9]);
|
||||
case 11: return sscanf(buffer, format, sVarArgs[0], sVarArgs[1], sVarArgs[2], sVarArgs[3], sVarArgs[4], sVarArgs[5], sVarArgs[6], sVarArgs[7], sVarArgs[8], sVarArgs[9], sVarArgs[10]);
|
||||
case 12: return sscanf(buffer, format, sVarArgs[0], sVarArgs[1], sVarArgs[2], sVarArgs[3], sVarArgs[4], sVarArgs[5], sVarArgs[6], sVarArgs[7], sVarArgs[8], sVarArgs[9], sVarArgs[10], sVarArgs[11]);
|
||||
case 13: return sscanf(buffer, format, sVarArgs[0], sVarArgs[1], sVarArgs[2], sVarArgs[3], sVarArgs[4], sVarArgs[5], sVarArgs[6], sVarArgs[7], sVarArgs[8], sVarArgs[9], sVarArgs[10], sVarArgs[11], sVarArgs[12]);
|
||||
case 14: return sscanf(buffer, format, sVarArgs[0], sVarArgs[1], sVarArgs[2], sVarArgs[3], sVarArgs[4], sVarArgs[5], sVarArgs[6], sVarArgs[7], sVarArgs[8], sVarArgs[9], sVarArgs[10], sVarArgs[11], sVarArgs[12], sVarArgs[13]);
|
||||
case 15: return sscanf(buffer, format, sVarArgs[0], sVarArgs[1], sVarArgs[2], sVarArgs[3], sVarArgs[4], sVarArgs[5], sVarArgs[6], sVarArgs[7], sVarArgs[8], sVarArgs[9], sVarArgs[10], sVarArgs[11], sVarArgs[12], sVarArgs[13], sVarArgs[14]);
|
||||
case 16: return sscanf(buffer, format, sVarArgs[0], sVarArgs[1], sVarArgs[2], sVarArgs[3], sVarArgs[4], sVarArgs[5], sVarArgs[6], sVarArgs[7], sVarArgs[8], sVarArgs[9], sVarArgs[10], sVarArgs[11], sVarArgs[12], sVarArgs[13], sVarArgs[14], sVarArgs[15]);
|
||||
case 17: return sscanf(buffer, format, sVarArgs[0], sVarArgs[1], sVarArgs[2], sVarArgs[3], sVarArgs[4], sVarArgs[5], sVarArgs[6], sVarArgs[7], sVarArgs[8], sVarArgs[9], sVarArgs[10], sVarArgs[11], sVarArgs[12], sVarArgs[13], sVarArgs[14], sVarArgs[15], sVarArgs[16]);
|
||||
case 18: return sscanf(buffer, format, sVarArgs[0], sVarArgs[1], sVarArgs[2], sVarArgs[3], sVarArgs[4], sVarArgs[5], sVarArgs[6], sVarArgs[7], sVarArgs[8], sVarArgs[9], sVarArgs[10], sVarArgs[11], sVarArgs[12], sVarArgs[13], sVarArgs[14], sVarArgs[15], sVarArgs[16], sVarArgs[17]);
|
||||
case 19: return sscanf(buffer, format, sVarArgs[0], sVarArgs[1], sVarArgs[2], sVarArgs[3], sVarArgs[4], sVarArgs[5], sVarArgs[6], sVarArgs[7], sVarArgs[8], sVarArgs[9], sVarArgs[10], sVarArgs[11], sVarArgs[12], sVarArgs[13], sVarArgs[14], sVarArgs[15], sVarArgs[16], sVarArgs[17], sVarArgs[18]);
|
||||
case 20: return sscanf(buffer, format, sVarArgs[0], sVarArgs[1], sVarArgs[2], sVarArgs[3], sVarArgs[4], sVarArgs[5], sVarArgs[6], sVarArgs[7], sVarArgs[8], sVarArgs[9], sVarArgs[10], sVarArgs[11], sVarArgs[12], sVarArgs[13], sVarArgs[14], sVarArgs[15], sVarArgs[16], sVarArgs[17], sVarArgs[18], sVarArgs[19]);
|
||||
}
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
S32 dFflushStdout()
|
||||
{
|
||||
return fflush(stdout);
|
||||
}
|
||||
|
||||
S32 dFflushStderr()
|
||||
{
|
||||
return fflush(stderr);
|
||||
}
|
||||
|
||||
void dQsort(void *base, U32 nelem, U32 width, S32 (QSORT_CALLBACK *fcmp)(const void *, const void *))
|
||||
{
|
||||
qsort(base, nelem, width, fcmp);
|
||||
}
|
105
engine/platformX86UNIX/x86UNIXThread.cc
Executable file
105
engine/platformX86UNIX/x86UNIXThread.cc
Executable file
@ -0,0 +1,105 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
#include "platform/platformThread.h"
|
||||
#include "platformX86UNIX/platformX86UNIX.h"
|
||||
#include "platform/platformSemaphore.h"
|
||||
#include <pthread.h>
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
struct x86UNIXThreadData
|
||||
{
|
||||
ThreadRunFunction mRunFunc;
|
||||
S32 mRunArg;
|
||||
Thread * mThread;
|
||||
void * mSemaphore;
|
||||
|
||||
x86UNIXThreadData()
|
||||
{
|
||||
mRunFunc = 0;
|
||||
mRunArg = 0;
|
||||
mThread = 0;
|
||||
mSemaphore = 0;
|
||||
};
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
Thread::Thread(ThreadRunFunction func, S32 arg, bool start_thread)
|
||||
{
|
||||
x86UNIXThreadData * threadData = new x86UNIXThreadData();
|
||||
threadData->mRunFunc = func;
|
||||
threadData->mRunArg = arg;
|
||||
threadData->mThread = this;
|
||||
threadData->mSemaphore = Semaphore::createSemaphore();
|
||||
|
||||
mData = reinterpret_cast<void*>(threadData);
|
||||
if (start_thread)
|
||||
start();
|
||||
}
|
||||
|
||||
Thread::~Thread()
|
||||
{
|
||||
join();
|
||||
|
||||
x86UNIXThreadData * threadData = reinterpret_cast<x86UNIXThreadData*>(mData);
|
||||
Semaphore::destroySemaphore(threadData->mSemaphore);
|
||||
delete threadData;
|
||||
}
|
||||
|
||||
static void *ThreadRunHandler(void * arg)
|
||||
{
|
||||
x86UNIXThreadData * threadData = reinterpret_cast<x86UNIXThreadData*>(arg);
|
||||
|
||||
threadData->mThread->run(threadData->mRunArg);
|
||||
Semaphore::releaseSemaphore(threadData->mSemaphore);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void Thread::start()
|
||||
{
|
||||
if(isAlive())
|
||||
return;
|
||||
|
||||
x86UNIXThreadData * threadData = reinterpret_cast<x86UNIXThreadData*>(mData);
|
||||
Semaphore::acquireSemaphore(threadData->mSemaphore);
|
||||
|
||||
pthread_t threadID;
|
||||
pthread_create(&threadID, NULL, ThreadRunHandler, mData);
|
||||
}
|
||||
|
||||
bool Thread::join()
|
||||
{
|
||||
if(!isAlive())
|
||||
return(false);
|
||||
|
||||
x86UNIXThreadData * threadData = reinterpret_cast<x86UNIXThreadData*>(mData);
|
||||
return(Semaphore::acquireSemaphore(threadData->mSemaphore));
|
||||
}
|
||||
|
||||
void Thread::run(S32 arg)
|
||||
{
|
||||
x86UNIXThreadData * threadData = reinterpret_cast<x86UNIXThreadData*>(mData);
|
||||
if(threadData->mRunFunc)
|
||||
threadData->mRunFunc(arg);
|
||||
}
|
||||
|
||||
bool Thread::isAlive()
|
||||
{
|
||||
x86UNIXThreadData * threadData = reinterpret_cast<x86UNIXThreadData*>(mData);
|
||||
|
||||
bool signal = Semaphore::acquireSemaphore(threadData->mSemaphore, false);
|
||||
if(signal)
|
||||
Semaphore::releaseSemaphore(threadData->mSemaphore);
|
||||
return(!signal);
|
||||
}
|
||||
|
||||
|
||||
U32 Thread::getCurrentThreadId()
|
||||
{
|
||||
return (U32)pthread_self();
|
||||
}
|
||||
|
100
engine/platformX86UNIX/x86UNIXTime.cc
Executable file
100
engine/platformX86UNIX/x86UNIXTime.cc
Executable file
@ -0,0 +1,100 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
#include "platformX86UNIX/platformX86UNIX.h"
|
||||
#include "platformX86UNIX/x86UNIXState.h"
|
||||
#include "time.h"
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <unistd.h>
|
||||
|
||||
U32 x86UNIXGetTickCount();
|
||||
//--------------------------------------
|
||||
void Platform::getLocalTime(LocalTime <)
|
||||
{
|
||||
struct tm *systime;
|
||||
time_t long_time;
|
||||
|
||||
time( &long_time ); // Get time as long integer.
|
||||
systime = localtime( &long_time ); // Convert to local time.
|
||||
|
||||
lt.sec = systime->tm_sec;
|
||||
lt.min = systime->tm_min;
|
||||
lt.hour = systime->tm_hour;
|
||||
lt.month = systime->tm_mon;
|
||||
lt.monthday = systime->tm_mday;
|
||||
lt.weekday = systime->tm_wday;
|
||||
lt.year = systime->tm_year;
|
||||
lt.yearday = systime->tm_yday;
|
||||
lt.isdst = systime->tm_isdst;
|
||||
}
|
||||
|
||||
U32 Platform::getTime()
|
||||
{
|
||||
time_t long_time;
|
||||
time( &long_time );
|
||||
return long_time;
|
||||
}
|
||||
|
||||
U32 Platform::getRealMilliseconds()
|
||||
{
|
||||
// struct rusage usageStats;
|
||||
// getrusage(RUSAGE_SELF, &usageStats);
|
||||
// return usageStats.ru_utime.tv_usec;
|
||||
return x86UNIXGetTickCount();
|
||||
}
|
||||
|
||||
U32 Platform::getVirtualMilliseconds()
|
||||
{
|
||||
return x86UNIXState->currentTime;
|
||||
}
|
||||
|
||||
void Platform::advanceTime(U32 delta)
|
||||
{
|
||||
x86UNIXState->currentTime += delta;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//-------------------------------------- x86UNIX Implementation
|
||||
//
|
||||
//
|
||||
static bool sg_initialized = false;
|
||||
static U32 sg_secsOffset = 0;
|
||||
//--------------------------------------
|
||||
U32 x86UNIXGetTickCount()
|
||||
{
|
||||
// TODO: What happens when crossing a day boundary?
|
||||
//
|
||||
timeval t;
|
||||
|
||||
if (sg_initialized == false) {
|
||||
sg_initialized = true;
|
||||
|
||||
gettimeofday(&t, NULL);
|
||||
sg_secsOffset = t.tv_sec;
|
||||
}
|
||||
|
||||
gettimeofday(&t, NULL);
|
||||
|
||||
U32 secs = t.tv_sec - sg_secsOffset;
|
||||
U32 uSecs = t.tv_usec;
|
||||
|
||||
// Make granularity 1 ms
|
||||
return (secs * 1000) + (uSecs / 1000);
|
||||
}
|
||||
|
||||
|
||||
void Platform::sleep(U32 ms)
|
||||
{
|
||||
// note: this will overflow if you want to sleep for more than 49 days. just so ye know.
|
||||
usleep( ms * 1000 );
|
||||
}
|
||||
|
269
engine/platformX86UNIX/x86UNIXUtils.cc
Executable file
269
engine/platformX86UNIX/x86UNIXUtils.cc
Executable file
@ -0,0 +1,269 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
#include <unistd.h>
|
||||
#include <termios.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/utsname.h>
|
||||
|
||||
// for UnixCommandExecutor
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "platformX86UNIX/platformX86UNIX.h"
|
||||
#include "platformX86UNIX/x86UNIXUtils.h"
|
||||
|
||||
UnixUtils *UUtils = NULL;
|
||||
UnixUtils utils;
|
||||
|
||||
UnixUtils::UnixUtils()
|
||||
{
|
||||
UUtils = this;
|
||||
|
||||
mUnameInfo = (struct utsname*)dRealMalloc(sizeof(struct utsname));;
|
||||
if (uname(mUnameInfo) == -1)
|
||||
{
|
||||
// oh well
|
||||
dRealFree(mUnameInfo);
|
||||
mUnameInfo = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
UnixUtils::~UnixUtils()
|
||||
{
|
||||
if (mUnameInfo != NULL)
|
||||
{
|
||||
dRealFree(mUnameInfo);
|
||||
mUnameInfo = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
const char* UnixUtils::getOSName()
|
||||
{
|
||||
if (mUnameInfo == NULL)
|
||||
return "";
|
||||
|
||||
return mUnameInfo->sysname;
|
||||
}
|
||||
|
||||
bool UnixUtils::inBackground()
|
||||
{
|
||||
int terminalGroupId = tcgetpgrp(fileno(stdin));
|
||||
int myPid = getpid();
|
||||
if (terminalGroupId != myPid)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// UnixCommandExecutor
|
||||
void UnixCommandExecutor::clearFields()
|
||||
{
|
||||
mRet = -1;
|
||||
mStdoutSave = -1;
|
||||
mStderrSave = -1;
|
||||
mPipeFiledes[0] = -1;
|
||||
mPipeFiledes[1] = -1;
|
||||
mChildPID = -1;
|
||||
mBytesRead = 0;
|
||||
mStdoutClosed = false;
|
||||
mStderrClosed = false;
|
||||
mChildExited = false;
|
||||
}
|
||||
|
||||
UnixCommandExecutor::UnixCommandExecutor()
|
||||
{
|
||||
clearFields();
|
||||
}
|
||||
|
||||
UnixCommandExecutor::~UnixCommandExecutor()
|
||||
{
|
||||
cleanup();
|
||||
}
|
||||
|
||||
int UnixCommandExecutor::exec(char* args[],
|
||||
char* stdoutCapture, int stdoutCaptureSize)
|
||||
{
|
||||
// check for shitty parameters
|
||||
if (args == NULL || stdoutCapture == NULL ||
|
||||
stdoutCaptureSize <= 0)
|
||||
return -666;
|
||||
|
||||
// we're going to be redirecting stdout, so save it so that we can
|
||||
// restore it
|
||||
mRet = dup(1);
|
||||
if (mRet == -1)
|
||||
{
|
||||
cleanup();
|
||||
return mRet;
|
||||
}
|
||||
mStdoutSave = mRet;
|
||||
|
||||
// save stderr
|
||||
mRet = dup(2);
|
||||
if (mRet == -1)
|
||||
{
|
||||
cleanup();
|
||||
return mRet;
|
||||
}
|
||||
mStderrSave = mRet;
|
||||
|
||||
// we'll need some pipe action for communicating with subprocess
|
||||
mRet = pipe(mPipeFiledes);
|
||||
if (mRet == -1)
|
||||
{
|
||||
cleanup();
|
||||
return mRet;
|
||||
}
|
||||
|
||||
// close stdout
|
||||
mRet = close(1);
|
||||
if (mRet == -1)
|
||||
{
|
||||
cleanup();
|
||||
return mRet;
|
||||
}
|
||||
mStdoutClosed = true;
|
||||
|
||||
// stderr just gets closed and the output discarded
|
||||
mRet = close(2);
|
||||
if (mRet == -1)
|
||||
{
|
||||
cleanup();
|
||||
return mRet;
|
||||
}
|
||||
mStderrClosed = true;
|
||||
|
||||
// dup the pipe output into stdout
|
||||
mRet = dup2(mPipeFiledes[1], 1);
|
||||
if (mRet == -1)
|
||||
{
|
||||
cleanup();
|
||||
return mRet;
|
||||
}
|
||||
|
||||
// fork
|
||||
mRet = fork();
|
||||
if (mRet == -1)
|
||||
{
|
||||
cleanup();
|
||||
return mRet;
|
||||
}
|
||||
|
||||
if (mRet == 0)
|
||||
{
|
||||
// child process
|
||||
|
||||
//close(mPipeFiledes[0]);
|
||||
mRet = execvp(args[0], args);
|
||||
// if exec returns, some bad shit went down, so just
|
||||
// get outta here
|
||||
exit(mRet);
|
||||
}
|
||||
|
||||
// parent process
|
||||
mChildPID = mRet;
|
||||
|
||||
// need to suck in data from pipe while child is running,
|
||||
// otherwise child will eventually block on write and we'll
|
||||
// wait forever
|
||||
memset(stdoutCapture, 0, stdoutCaptureSize);
|
||||
|
||||
// set input to be non blocking so that we don't block on read
|
||||
mRet = fcntl(mPipeFiledes[0], F_SETFL, O_NONBLOCK);
|
||||
if (mRet == -1)
|
||||
{
|
||||
cleanup();
|
||||
return mRet;
|
||||
}
|
||||
|
||||
// check to see if child has exited
|
||||
mRet = waitpid(mChildPID, NULL, WNOHANG);
|
||||
while (mRet == 0)
|
||||
{
|
||||
// not exited, read some data
|
||||
mRet = read(mPipeFiledes[0], stdoutCapture + mBytesRead,
|
||||
stdoutCaptureSize - mBytesRead);
|
||||
// any error that isn't EAGAIN means we should exit
|
||||
if (mRet == -1 && errno != EAGAIN)
|
||||
{
|
||||
cleanup();
|
||||
return mRet;
|
||||
}
|
||||
|
||||
// if the read was ok, increment bytes read
|
||||
if (mRet != -1)
|
||||
mBytesRead += mRet;
|
||||
|
||||
// check again for child exit
|
||||
mRet = waitpid(mChildPID, NULL, WNOHANG);
|
||||
}
|
||||
|
||||
// check for error from waitpid
|
||||
if (mRet == -1 && errno != ECHILD)
|
||||
{
|
||||
cleanup();
|
||||
return mRet;
|
||||
}
|
||||
|
||||
// if we get here, the child exited
|
||||
mChildExited = true;
|
||||
|
||||
// read final bit of data
|
||||
mRet = read(mPipeFiledes[0], stdoutCapture + mBytesRead,
|
||||
stdoutCaptureSize - mBytesRead);
|
||||
if (mRet == -1 && errno != EAGAIN)
|
||||
{
|
||||
cleanup();
|
||||
return mRet;
|
||||
}
|
||||
|
||||
if (mRet != -1)
|
||||
mBytesRead += mRet;
|
||||
|
||||
// done...cleanup
|
||||
cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void UnixCommandExecutor::cleanup()
|
||||
{
|
||||
// if child spawned and not exited, wait
|
||||
if (mChildPID > 0 && !mChildExited)
|
||||
waitpid(mChildPID, NULL, 0);
|
||||
// close pipe descriptors
|
||||
if (mPipeFiledes[0] != -1)
|
||||
close(mPipeFiledes[0]);
|
||||
if (mPipeFiledes[1] != -1)
|
||||
close(mPipeFiledes[1]);
|
||||
// if stdout is redirected, restore it
|
||||
if (mStdoutClosed && mStdoutSave != -1)
|
||||
dup2(mStdoutSave, 1);
|
||||
// close stdout save descriptor
|
||||
if (mStdoutSave != -1)
|
||||
close(mStdoutSave);
|
||||
// if stderr is redirected, restore it
|
||||
if (mStderrClosed && mStderrSave != -1)
|
||||
dup2(mStderrSave, 2);
|
||||
// close stderr save descriptor
|
||||
if (mStderrSave != -1)
|
||||
close(mStderrSave);
|
||||
|
||||
clearFields();
|
||||
}
|
||||
|
||||
/* Usage:
|
||||
UnixCommandExecutor exec;
|
||||
char* args[] = { "ps", "-aux", NULL };
|
||||
char data[20000];
|
||||
int ret = exec.exec(args, data, sizeof(data));
|
||||
printf("%s", data);
|
||||
*/
|
75
engine/platformX86UNIX/x86UNIXUtils.h
Executable file
75
engine/platformX86UNIX/x86UNIXUtils.h
Executable file
@ -0,0 +1,75 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
#ifndef _X86UNIXUTILS_H_
|
||||
#define _X86UNIXUTILS_H_
|
||||
|
||||
struct utsname;
|
||||
|
||||
class UnixUtils
|
||||
{
|
||||
public:
|
||||
UnixUtils();
|
||||
virtual ~UnixUtils();
|
||||
|
||||
/**
|
||||
Returns true if we're running in the background, false otherwise.
|
||||
There's no "standard" way to determine this in unix, but
|
||||
modern job control unices should support the method described
|
||||
here:
|
||||
|
||||
http://www.faqs.org/faqs/unix-faq/faq/part3/
|
||||
|
||||
(question 3.7)
|
||||
*/
|
||||
bool inBackground();
|
||||
|
||||
/**
|
||||
Returns the name of the OS, as reported by uname.
|
||||
*/
|
||||
const char* getOSName();
|
||||
|
||||
private:
|
||||
struct utsname* mUnameInfo;
|
||||
};
|
||||
|
||||
extern UnixUtils *UUtils;
|
||||
|
||||
// utility class for running a unix command and capturing its output
|
||||
class UnixCommandExecutor
|
||||
{
|
||||
private:
|
||||
int mRet;
|
||||
int mStdoutSave;
|
||||
int mStderrSave;
|
||||
int mPipeFiledes[2];
|
||||
int mChildPID;
|
||||
int mBytesRead;
|
||||
bool mStdoutClosed;
|
||||
bool mStderrClosed;
|
||||
bool mChildExited;
|
||||
|
||||
void clearFields();
|
||||
void cleanup();
|
||||
|
||||
public:
|
||||
UnixCommandExecutor();
|
||||
~UnixCommandExecutor();
|
||||
|
||||
// Runs the specified command.
|
||||
// - args is a null terminated list of the command and its arguments,
|
||||
// e.g: "ps", "-aux", NULL
|
||||
// - stdoutCapture is the buffer where stdout data will be stored
|
||||
// - stdoutCaptureSize is the size of the buffer
|
||||
// None of these parameters may be null. stdoutCaptureSize must be > 0
|
||||
//
|
||||
// returns -2 if the parameters are bad. returns -1 if some other
|
||||
// error occurs, check errno for the exact error.
|
||||
int exec(char* args[], char* stdoutCapture, int stdoutCaptureSize);
|
||||
};
|
||||
|
||||
#endif
|
897
engine/platformX86UNIX/x86UNIXWindow.cc
Executable file
897
engine/platformX86UNIX/x86UNIXWindow.cc
Executable file
@ -0,0 +1,897 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
#include "console/console.h"
|
||||
#include "core/fileStream.h"
|
||||
#include "game/resource.h"
|
||||
#include "game/version.h"
|
||||
#include "math/mRandom.h"
|
||||
#include "platformX86UNIX/platformX86UNIX.h"
|
||||
#include "platformX86UNIX/x86UNIXStdConsole.h"
|
||||
#include "platform/event.h"
|
||||
#include "platform/gameInterface.h"
|
||||
#include "platform/platform.h"
|
||||
#include "platform/platformAL.h"
|
||||
#include "platform/platformInput.h"
|
||||
#include "platform/platformVideo.h"
|
||||
#include "platform/profiler.h"
|
||||
#include "platformX86UNIX/platformGL.h"
|
||||
#include "platformX86UNIX/x86UNIXOGLVideo.h"
|
||||
#include "platformX86UNIX/x86UNIXState.h"
|
||||
|
||||
#ifndef DEDICATED
|
||||
#include "platformX86UNIX/x86UNIXMessageBox.h"
|
||||
#include "platformX86UNIX/x86UNIXInputManager.h"
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h> // fork, execvp, chdir
|
||||
#include <time.h> // nanosleep
|
||||
|
||||
#ifndef DEDICATED
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xos.h>
|
||||
|
||||
#include <SDL/SDL.h>
|
||||
#include <SDL/SDL_syswm.h>
|
||||
#include <SDL/SDL_version.h>
|
||||
#endif
|
||||
|
||||
x86UNIXPlatformState *x86UNIXState;
|
||||
|
||||
bool DisplayPtrManager::sgDisplayLocked = false;
|
||||
LockFunc_t DisplayPtrManager::sgLockFunc = NULL;
|
||||
LockFunc_t DisplayPtrManager::sgUnlockFunc = NULL;
|
||||
|
||||
static U32 lastTimeTick;
|
||||
static MRandomLCG sgPlatRandom;
|
||||
|
||||
#ifndef DEDICATED
|
||||
extern void InstallRedBookDevices();
|
||||
extern void PollRedbookDevices();
|
||||
extern bool InitOpenGL();
|
||||
// This is called when some X client sends
|
||||
// a selection event (e.g. SelectionRequest)
|
||||
// to the window
|
||||
extern void NotifySelectionEvent(XEvent& event);
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static S32 ParseCommandLine(S32 argc, const char **argv,
|
||||
Vector<char*>& newCommandLine)
|
||||
{
|
||||
x86UNIXState->setExePathName(argv[0]);
|
||||
bool foundDedicated = false;
|
||||
|
||||
for ( int i=0; i < argc; i++ )
|
||||
{
|
||||
// look for platform specific args
|
||||
if (dStrcmp(argv[i], "-version") == 0)
|
||||
{
|
||||
dPrintf("%s (built on %s)\n", getVersionString(), getCompileTimeString());
|
||||
dPrintf("gcc: %s\n", __VERSION__);
|
||||
return 1;
|
||||
}
|
||||
if (dStrcmp(argv[i], "-cdaudio") == 0)
|
||||
{
|
||||
x86UNIXState->setCDAudioEnabled(true);
|
||||
continue;
|
||||
}
|
||||
if (dStrcmp(argv[i], "-dedicated") == 0)
|
||||
{
|
||||
foundDedicated = true;
|
||||
// no continue because dedicated is also handled by script
|
||||
}
|
||||
if (dStrcmp(argv[i], "-dsleep") == 0)
|
||||
{
|
||||
x86UNIXState->setDSleep(true);
|
||||
continue;
|
||||
}
|
||||
if (dStrcmp(argv[i], "-nohomedir") == 0)
|
||||
{
|
||||
x86UNIXState->setUseRedirect(false);
|
||||
continue;
|
||||
}
|
||||
if (dStrcmp(argv[i], "-chdir") == 0)
|
||||
{
|
||||
if ( ++i >= argc )
|
||||
{
|
||||
dPrintf("Follow -chdir option with the desired working directory.\n");
|
||||
return 1;
|
||||
}
|
||||
if (chdir(argv[i]) == -1)
|
||||
{
|
||||
dPrintf("Unable to chdir to %s: %s\n", argv[i], strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// copy the arg into newCommandLine
|
||||
int argLen = dStrlen(argv[i]) + 1;
|
||||
char* argBuf = new char[argLen]; // this memory is deleted in main()
|
||||
dStrncpy(argBuf, argv[i], argLen);
|
||||
newCommandLine.push_back(argBuf);
|
||||
}
|
||||
x86UNIXState->setDedicated(foundDedicated);
|
||||
#if defined(DEDICATED) && !defined(TORQUE_ENGINE)
|
||||
if (!foundDedicated)
|
||||
{
|
||||
dPrintf("This is a dedicated server build. You must supply the -dedicated command line parameter.\n");
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void DetectWindowingSystem()
|
||||
{
|
||||
#ifndef DEDICATED
|
||||
Display* dpy = XOpenDisplay(NULL);
|
||||
if (dpy != NULL)
|
||||
{
|
||||
x86UNIXState->setXWindowsRunning(true);
|
||||
XCloseDisplay(dpy);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void InitWindow(const Point2I &initialSize, const char *name)
|
||||
{
|
||||
x86UNIXState->setWindowSize(initialSize);
|
||||
x86UNIXState->setWindowName(name);
|
||||
}
|
||||
|
||||
#ifndef DEDICATED
|
||||
//------------------------------------------------------------------------------
|
||||
static bool InitSDL()
|
||||
{
|
||||
if (SDL_Init(SDL_INIT_VIDEO) != 0)
|
||||
return false;
|
||||
|
||||
atexit(SDL_Quit);
|
||||
|
||||
SDL_SysWMinfo sysinfo;
|
||||
SDL_VERSION(&sysinfo.version);
|
||||
if (SDL_GetWMInfo(&sysinfo) == 0)
|
||||
return false;
|
||||
|
||||
x86UNIXState->setDisplayPointer(sysinfo.info.x11.display);
|
||||
DisplayPtrManager::setDisplayLockFunction(sysinfo.info.x11.lock_func);
|
||||
DisplayPtrManager::setDisplayUnlockFunction(sysinfo.info.x11.unlock_func);
|
||||
|
||||
DisplayPtrManager xdisplay;
|
||||
Display* display = xdisplay.getDisplayPointer();
|
||||
|
||||
x86UNIXState->setScreenNumber(
|
||||
DefaultScreen( display ) );
|
||||
x86UNIXState->setScreenPointer(
|
||||
DefaultScreenOfDisplay( display ) );
|
||||
|
||||
x86UNIXState->setDesktopSize(
|
||||
(S32) DisplayWidth(
|
||||
display,
|
||||
x86UNIXState->getScreenNumber()),
|
||||
(S32) DisplayHeight(
|
||||
display,
|
||||
x86UNIXState->getScreenNumber())
|
||||
);
|
||||
x86UNIXState->setDesktopBpp(
|
||||
(S32) DefaultDepth(
|
||||
display,
|
||||
x86UNIXState->getScreenNumber()));
|
||||
|
||||
// indicate that we want sys WM messages
|
||||
SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void ProcessSYSWMEvent(const SDL_Event& event)
|
||||
{
|
||||
XEvent& xevent = event.syswm.msg->event.xevent;
|
||||
//Con::printf("xevent : %d", xevent.type);
|
||||
switch (xevent.type)
|
||||
{
|
||||
case SelectionRequest:
|
||||
// somebody wants our clipboard
|
||||
NotifySelectionEvent(xevent);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void SetAppState()
|
||||
{
|
||||
U8 state = SDL_GetAppState();
|
||||
|
||||
// if we're not active but we have appactive and inputfocus, set window
|
||||
// active and reactivate input
|
||||
if ((!x86UNIXState->windowActive() || !Input::isActive()) &&
|
||||
state & SDL_APPACTIVE &&
|
||||
state & SDL_APPINPUTFOCUS)
|
||||
{
|
||||
x86UNIXState->setWindowActive(true);
|
||||
Input::reactivate();
|
||||
}
|
||||
// if we are active, but we don't have appactive or input focus,
|
||||
// deactivate input (if window not locked) and clear windowActive
|
||||
else if (x86UNIXState->windowActive() &&
|
||||
!(state & SDL_APPACTIVE && state & SDL_APPINPUTFOCUS))
|
||||
{
|
||||
if (x86UNIXState->windowLocked())
|
||||
Input::deactivate();
|
||||
x86UNIXState->setWindowActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static S32 NumEventsPending()
|
||||
{
|
||||
static const int MaxEvents = 255;
|
||||
static SDL_Event events[MaxEvents];
|
||||
|
||||
SDL_PumpEvents();
|
||||
return SDL_PeepEvents(events, MaxEvents, SDL_PEEKEVENT, SDL_ALLEVENTS);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void PrintSDLEventQueue()
|
||||
{
|
||||
static const int MaxEvents = 255;
|
||||
static SDL_Event events[MaxEvents];
|
||||
|
||||
SDL_PumpEvents();
|
||||
S32 numEvents = SDL_PeepEvents(
|
||||
events, MaxEvents, SDL_PEEKEVENT, SDL_ALLEVENTS);
|
||||
if (numEvents <= 0)
|
||||
{
|
||||
dPrintf("SDL Event Queue is empty\n");
|
||||
return;
|
||||
}
|
||||
|
||||
dPrintf("SDL Event Queue:\n");
|
||||
for (int i = 0; i < numEvents; ++i)
|
||||
{
|
||||
const char *eventType;
|
||||
switch (events[i].type)
|
||||
{
|
||||
case SDL_NOEVENT: eventType = "SDL_NOEVENT"; break;
|
||||
case SDL_ACTIVEEVENT: eventType = "SDL_ACTIVEEVENT"; break;
|
||||
case SDL_KEYDOWN: eventType = "SDL_KEYDOWN"; break;
|
||||
case SDL_KEYUP: eventType = "SDL_KEYUP"; break;
|
||||
case SDL_MOUSEMOTION: eventType = "SDL_MOUSEMOTION"; break;
|
||||
case SDL_MOUSEBUTTONDOWN: eventType = "SDL_MOUSEBUTTONDOWN"; break;
|
||||
case SDL_MOUSEBUTTONUP: eventType = "SDL_MOUSEBUTTONUP"; break;
|
||||
case SDL_JOYAXISMOTION: eventType = "SDL_JOYAXISMOTION"; break;
|
||||
case SDL_JOYBALLMOTION: eventType = "SDL_JOYBALLMOTION"; break;
|
||||
case SDL_JOYHATMOTION: eventType = "SDL_JOYHATMOTION"; break;
|
||||
case SDL_JOYBUTTONDOWN: eventType = "SDL_JOYBUTTONDOWN"; break;
|
||||
case SDL_JOYBUTTONUP: eventType = "SDL_JOYBUTTONUP"; break;
|
||||
case SDL_QUIT: eventType = "SDL_QUIT"; break;
|
||||
case SDL_SYSWMEVENT: eventType = "SDL_SYSWMEVENT"; break;
|
||||
case SDL_VIDEORESIZE: eventType = "SDL_VIDEORESIZE"; break;
|
||||
case SDL_VIDEOEXPOSE: eventType = "SDL_VIDEOEXPOSE"; break;
|
||||
/* Events SDL_USEREVENT through SDL_MAXEVENTS-1 are for your use */
|
||||
case SDL_USEREVENT: eventType = "SDL_USEREVENT"; break;
|
||||
default: eventType = "UNKNOWN!"; break;
|
||||
}
|
||||
dPrintf("Event %d: %s\n", i, eventType);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static bool ProcessMessages()
|
||||
{
|
||||
static const int MaxEvents = 255;
|
||||
static const U32 Mask =
|
||||
SDL_QUITMASK | SDL_VIDEORESIZEMASK | SDL_VIDEOEXPOSEMASK |
|
||||
SDL_ACTIVEEVENTMASK | SDL_SYSWMEVENTMASK |
|
||||
SDL_EVENTMASK(SDL_USEREVENT);
|
||||
static SDL_Event events[MaxEvents];
|
||||
|
||||
SDL_PumpEvents();
|
||||
S32 numEvents = SDL_PeepEvents(events, MaxEvents, SDL_GETEVENT, Mask);
|
||||
if (numEvents == 0)
|
||||
return true;
|
||||
for (int i = 0; i < numEvents; ++i)
|
||||
{
|
||||
SDL_Event& event = events[i];
|
||||
switch (event.type)
|
||||
{
|
||||
case SDL_QUIT:
|
||||
return false;
|
||||
break;
|
||||
case SDL_VIDEORESIZE:
|
||||
case SDL_VIDEOEXPOSE:
|
||||
Game->refreshWindow();
|
||||
break;
|
||||
case SDL_USEREVENT:
|
||||
if (event.user.code == TORQUE_SETVIDEOMODE)
|
||||
{
|
||||
SetAppState();
|
||||
// SDL will send a motion event to restore the mouse position
|
||||
// on the new window. Ignore that if the window is locked.
|
||||
if (x86UNIXState->windowLocked())
|
||||
{
|
||||
SDL_Event tempEvent;
|
||||
SDL_PeepEvents(&tempEvent, 1, SDL_GETEVENT,
|
||||
SDL_MOUSEMOTIONMASK);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SDL_ACTIVEEVENT:
|
||||
SetAppState();
|
||||
break;
|
||||
case SDL_SYSWMEVENT:
|
||||
ProcessSYSWMEvent(event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// send a destroy window event to the window. assumes
|
||||
// window is created.
|
||||
void SendQuitEvent()
|
||||
{
|
||||
SDL_Event quitevent;
|
||||
quitevent.type = SDL_QUIT;
|
||||
SDL_PushEvent(&quitevent);
|
||||
}
|
||||
#endif // DEDICATED
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static inline void Sleep(int secs, int nanoSecs)
|
||||
{
|
||||
timespec sleeptime;
|
||||
sleeptime.tv_sec = secs;
|
||||
sleeptime.tv_nsec = nanoSecs;
|
||||
nanosleep(&sleeptime, NULL);
|
||||
}
|
||||
|
||||
#ifndef DEDICATED
|
||||
struct AlertWinState
|
||||
{
|
||||
bool fullScreen;
|
||||
bool cursorHidden;
|
||||
bool inputGrabbed;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void DisplayErrorAlert(const char* errMsg, bool showSDLError)
|
||||
{
|
||||
char fullErrMsg[2048];
|
||||
dStrncpy(fullErrMsg, errMsg, sizeof(fullErrMsg));
|
||||
|
||||
if (showSDLError)
|
||||
{
|
||||
char* sdlerror = SDL_GetError();
|
||||
if (sdlerror != NULL && dStrlen(sdlerror) > 0)
|
||||
{
|
||||
dStrcat(fullErrMsg, " (Error: ");
|
||||
dStrcat(fullErrMsg, sdlerror);
|
||||
dStrcat(fullErrMsg, ")");
|
||||
}
|
||||
}
|
||||
|
||||
Platform::AlertOK("Error", fullErrMsg);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static inline void AlertDisableVideo(AlertWinState& state)
|
||||
{
|
||||
|
||||
state.fullScreen = Video::isFullScreen();
|
||||
state.cursorHidden = (SDL_ShowCursor(SDL_QUERY) == SDL_DISABLE);
|
||||
state.inputGrabbed = (SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_ON);
|
||||
|
||||
if (state.fullScreen)
|
||||
SDL_WM_ToggleFullScreen(SDL_GetVideoSurface());
|
||||
if (state.cursorHidden)
|
||||
SDL_ShowCursor(SDL_ENABLE);
|
||||
if (state.inputGrabbed)
|
||||
SDL_WM_GrabInput(SDL_GRAB_OFF);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static inline void AlertEnableVideo(AlertWinState& state)
|
||||
{
|
||||
if (state.fullScreen)
|
||||
SDL_WM_ToggleFullScreen(SDL_GetVideoSurface());
|
||||
if (state.cursorHidden)
|
||||
SDL_ShowCursor(SDL_DISABLE);
|
||||
if (state.inputGrabbed)
|
||||
SDL_WM_GrabInput(SDL_GRAB_ON);
|
||||
}
|
||||
#endif // DEDICATED
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void Platform::AlertOK(const char *windowTitle, const char *message)
|
||||
{
|
||||
#ifndef DEDICATED
|
||||
if (x86UNIXState->isXWindowsRunning())
|
||||
{
|
||||
AlertWinState state;
|
||||
AlertDisableVideo(state);
|
||||
|
||||
DisplayPtrManager xdisplay;
|
||||
XMessageBox mBox(xdisplay.getDisplayPointer());
|
||||
mBox.alertOK(windowTitle, message);
|
||||
|
||||
AlertEnableVideo(state);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (Con::isActive() && StdConsole::isEnabled())
|
||||
Con::printf("Alert: %s %s", windowTitle, message);
|
||||
else
|
||||
dPrintf("Alert: %s %s\n", windowTitle, message);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool Platform::AlertOKCancel(const char *windowTitle, const char *message)
|
||||
{
|
||||
#ifndef DEDICATED
|
||||
if (x86UNIXState->isXWindowsRunning())
|
||||
{
|
||||
AlertWinState state;
|
||||
AlertDisableVideo(state);
|
||||
|
||||
DisplayPtrManager xdisplay;
|
||||
XMessageBox mBox(xdisplay.getDisplayPointer());
|
||||
bool val =
|
||||
mBox.alertOKCancel(windowTitle, message) == XMessageBox::OK;
|
||||
|
||||
AlertEnableVideo(state);
|
||||
return val;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (Con::isActive() && StdConsole::isEnabled())
|
||||
Con::printf("Alert: %s %s", windowTitle, message);
|
||||
else
|
||||
dPrintf("Alert: %s %s\n", windowTitle, message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool Platform::AlertRetry(const char *windowTitle, const char *message)
|
||||
{
|
||||
#ifndef DEDICATED
|
||||
if (x86UNIXState->isXWindowsRunning())
|
||||
{
|
||||
AlertWinState state;
|
||||
AlertDisableVideo(state);
|
||||
|
||||
DisplayPtrManager xdisplay;
|
||||
XMessageBox mBox(xdisplay.getDisplayPointer());
|
||||
bool val =
|
||||
mBox.alertRetryCancel(windowTitle, message) == XMessageBox::Retry;
|
||||
|
||||
AlertEnableVideo(state);
|
||||
return val;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (Con::isActive() && StdConsole::isEnabled())
|
||||
Con::printf("Alert: %s %s", windowTitle, message);
|
||||
else
|
||||
dPrintf("Alert: %s %s\n", windowTitle, message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool Platform::excludeOtherInstances(const char *mutexName)
|
||||
{
|
||||
return AcquireProcessMutex(mutexName);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void Platform::enableKeyboardTranslation(void)
|
||||
{
|
||||
#ifndef DEDICATED
|
||||
// JMQ: not sure if this is needed for i18n keyboards
|
||||
//SDL_EnableUNICODE( 1 );
|
||||
// SDL_EnableKeyRepeat(
|
||||
// SDL_DEFAULT_REPEAT_DELAY,
|
||||
// SDL_DEFAULT_REPEAT_INTERVAL);
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void Platform::disableKeyboardTranslation(void)
|
||||
{
|
||||
#ifndef DEDICATED
|
||||
//SDL_EnableUNICODE( 0 );
|
||||
// SDL_EnableKeyRepeat(0, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void Platform::setWindowLocked(bool locked)
|
||||
{
|
||||
#ifndef DEDICATED
|
||||
x86UNIXState->setWindowLocked(locked);
|
||||
|
||||
UInputManager* uInputManager =
|
||||
dynamic_cast<UInputManager*>( Input::getManager() );
|
||||
|
||||
if ( uInputManager && uInputManager->isEnabled() &&
|
||||
Input::isActive() )
|
||||
uInputManager->setWindowLocked(locked);
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void Platform::minimizeWindow()
|
||||
{
|
||||
#ifndef DEDICATED
|
||||
if (x86UNIXState->windowCreated())
|
||||
SDL_WM_IconifyWindow();
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void Platform::process()
|
||||
{
|
||||
PROFILE_START(XUX_PlatformProcess);
|
||||
stdConsole->process();
|
||||
|
||||
if (x86UNIXState->windowCreated())
|
||||
{
|
||||
#ifndef DEDICATED
|
||||
// process window events
|
||||
PROFILE_START(XUX_ProcessMessages);
|
||||
bool quit = !ProcessMessages();
|
||||
PROFILE_END();
|
||||
if(quit)
|
||||
{
|
||||
// generate a quit event
|
||||
Event quitEvent;
|
||||
quitEvent.type = QuitEventType;
|
||||
Game->postEvent(quitEvent);
|
||||
}
|
||||
|
||||
// process input events
|
||||
PROFILE_START(XUX_InputProcess);
|
||||
Input::process();
|
||||
PROFILE_END();
|
||||
|
||||
// poll redbook state
|
||||
PROFILE_START(XUX_PollRedbookDevices);
|
||||
PollRedbookDevices();
|
||||
PROFILE_END();
|
||||
|
||||
// if we're not the foreground window, sleep for 1 ms
|
||||
if (!x86UNIXState->windowActive())
|
||||
Sleep(0, getBackgroundSleepTime() * 1000000);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
// no window
|
||||
// if we're not in journal mode, sleep for 1 ms
|
||||
// JMQ: since linux's minimum sleep latency seems to be 20ms, this can
|
||||
// increase player pings by 10-20ms in the dedicated server. So
|
||||
// you have to use -dsleep to enable it. the server sleeps anyway when
|
||||
// there are no players connected.
|
||||
// JMQ: recent kernels (such as RH 8.0 2.4.18) reduce the latency
|
||||
// to 2-4 ms on average.
|
||||
if (!Game->isJournalReading() && (x86UNIXState->getDSleep() ||
|
||||
Con::getIntVariable("Server::PlayerCount") -
|
||||
Con::getIntVariable("Server::BotCount") <= 0))
|
||||
{
|
||||
PROFILE_START(XUX_Sleep);
|
||||
Sleep(0, getBackgroundSleepTime() * 1000000);
|
||||
PROFILE_END();
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef DEDICATED
|
||||
#if 0
|
||||
// JMQ: disabled this because it may fire mistakenly in some configurations.
|
||||
// sdl's default event handling scheme should be enough.
|
||||
// crude check to make sure that we're not loading up events. the sdl
|
||||
// event queue should never have more than (say) 25 events in it at this
|
||||
// point
|
||||
const int MaxEvents = 25;
|
||||
if (NumEventsPending() > MaxEvents)
|
||||
{
|
||||
PrintSDLEventQueue();
|
||||
AssertFatal(false, "The SDL event queue has too many events!");
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
PROFILE_END();
|
||||
}
|
||||
|
||||
// extern U32 calculateCRC(void * buffer, S32 len, U32 crcVal );
|
||||
|
||||
// #if defined(DEBUG) || defined(INTERNAL_RELEASE)
|
||||
// static U32 stubCRC = 0;
|
||||
// #else
|
||||
// static U32 stubCRC = 0xEA63F56C;
|
||||
// #endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
const Point2I &Platform::getWindowSize()
|
||||
{
|
||||
return x86UNIXState->getWindowSize();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void Platform::setWindowSize( U32 newWidth, U32 newHeight )
|
||||
{
|
||||
x86UNIXState->setWindowSize( (S32) newWidth, (S32) newHeight );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void Platform::shutdown()
|
||||
{
|
||||
Cleanup();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void Platform::init()
|
||||
{
|
||||
// Set the platform variable for the scripts
|
||||
Con::setVariable( "$platform", "x86UNIX" );
|
||||
#if defined(__linux__)
|
||||
Con::setVariable( "$platformUnixType", "Linux" );
|
||||
#elif defined(__OpenBSD__)
|
||||
Con::setVariable( "$platformUnixType", "OpenBSD" );
|
||||
#else
|
||||
Con::setVariable( "$platformUnixType", "Unknown" );
|
||||
#endif
|
||||
|
||||
StdConsole::create();
|
||||
|
||||
#ifndef DEDICATED
|
||||
// if we're not dedicated do more initialization
|
||||
if (!x86UNIXState->isDedicated())
|
||||
{
|
||||
// init SDL
|
||||
if (!InitSDL())
|
||||
{
|
||||
DisplayErrorAlert("Unable to initialize SDL.");
|
||||
ImmediateShutdown(1);
|
||||
}
|
||||
|
||||
// initialize input
|
||||
Input::init();
|
||||
|
||||
// initialize redbook devices
|
||||
if (x86UNIXState->getCDAudioEnabled())
|
||||
InstallRedBookDevices();
|
||||
|
||||
Con::printf( "Video Init:" );
|
||||
|
||||
// load gl library
|
||||
if (!GLLoader::OpenGLInit())
|
||||
{
|
||||
DisplayErrorAlert("Unable to initialize OpenGL.");
|
||||
ImmediateShutdown(1);
|
||||
}
|
||||
|
||||
// initialize video
|
||||
Video::init();
|
||||
if ( Video::installDevice( OpenGLDevice::create() ) )
|
||||
Con::printf( " OpenGL display device detected." );
|
||||
else
|
||||
Con::printf( " OpenGL display device not detected." );
|
||||
|
||||
Con::printf(" ");
|
||||
}
|
||||
#endif
|
||||
// if we are dedicated, do sleep timing and display results
|
||||
if (x86UNIXState->isDedicated())
|
||||
{
|
||||
const S32 MaxSleepIter = 10;
|
||||
U32 totalSleepTime = 0;
|
||||
U32 start;
|
||||
for (S32 i = 0; i < MaxSleepIter; ++i)
|
||||
{
|
||||
start = Platform::getRealMilliseconds();
|
||||
Sleep(0, 1000000);
|
||||
totalSleepTime += Platform::getRealMilliseconds() - start;
|
||||
}
|
||||
U32 average = static_cast<U32>(totalSleepTime / MaxSleepIter);
|
||||
|
||||
Con::printf("Sleep latency: %ums", average);
|
||||
// dPrintf as well, since console output won't be visible yet
|
||||
dPrintf("Sleep latency: %ums\n", average);
|
||||
if (!x86UNIXState->getDSleep() && average < 10)
|
||||
{
|
||||
const char* msg = "Sleep latency ok, enabling dsleep for lower cpu " \
|
||||
"utilization";
|
||||
Con::printf("%s", msg);
|
||||
dPrintf("%s\n", msg);
|
||||
x86UNIXState->setDSleep(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void Platform::initWindow(const Point2I &initialSize, const char *name)
|
||||
{
|
||||
#ifndef DEDICATED
|
||||
// initialize window
|
||||
InitWindow(initialSize, name);
|
||||
if (!InitOpenGL())
|
||||
ImmediateShutdown(1);
|
||||
#endif
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
F32 Platform::getRandom()
|
||||
{
|
||||
return sgPlatRandom.randF();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Web browser function:
|
||||
//------------------------------------------------------------------------------
|
||||
bool Platform::openWebBrowser( const char* webAddress )
|
||||
{
|
||||
if (!webAddress || dStrlen(webAddress)==0)
|
||||
return false;
|
||||
|
||||
// look for a browser preference variable
|
||||
// JMQTODO: be nice to implement some UI to customize this
|
||||
const char* webBrowser = Con::getVariable("Pref::Unix::WebBrowser");
|
||||
if (dStrlen(webBrowser) == 0)
|
||||
webBrowser = NULL;
|
||||
|
||||
pid_t pid = fork();
|
||||
if (pid == -1)
|
||||
{
|
||||
Con::printf("WARNING: Platform::openWebBrowser failed to fork");
|
||||
return false;
|
||||
}
|
||||
else if (pid != 0)
|
||||
{
|
||||
// parent
|
||||
if (Video::isFullScreen())
|
||||
Video::toggleFullScreen();
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (pid == 0)
|
||||
{
|
||||
// child
|
||||
// try to exec konqueror, then netscape
|
||||
char* argv[3];
|
||||
argv[0] = "";
|
||||
argv[1] = const_cast<char*>(webAddress);
|
||||
argv[2] = 0;
|
||||
|
||||
int ok = -1;
|
||||
|
||||
// if execvp returns, it means it couldn't execute the program
|
||||
if (webBrowser != NULL)
|
||||
ok = execvp(webBrowser, argv);
|
||||
|
||||
ok = execvp("konqueror", argv);
|
||||
ok = execvp("mozilla", argv);
|
||||
ok = execvp("netscape", argv);
|
||||
// use dPrintf instead of Con here since we're now in another process,
|
||||
dPrintf("WARNING: Platform::openWebBrowser: couldn't launch a web browser\n");
|
||||
_exit(-1);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Con::printf("WARNING: Platform::openWebBrowser: forking problem");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Login password routines:
|
||||
//------------------------------------------------------------------------------
|
||||
const char* Platform::getLoginPassword()
|
||||
{
|
||||
Con::printf("WARNING: Platform::getLoginPassword() is unimplemented");
|
||||
return "";
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool Platform::setLoginPassword( const char* password )
|
||||
{
|
||||
Con::printf("WARNING: Platform::setLoginPassword is unimplemented");
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
void TimeManager::process()
|
||||
{
|
||||
U32 curTime = Platform::getRealMilliseconds();
|
||||
TimeEvent event;
|
||||
event.elapsedTime = curTime - lastTimeTick;
|
||||
if(event.elapsedTime > sgTimeManagerProcessInterval)
|
||||
{
|
||||
lastTimeTick = curTime;
|
||||
Game->postEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
ConsoleFunction( getDesktopResolution, const char*, 1, 1,
|
||||
"getDesktopResolution()" )
|
||||
{
|
||||
if (!x86UNIXState->windowCreated())
|
||||
return "0 0 0";
|
||||
|
||||
char buffer[256];
|
||||
char* returnString = Con::getReturnBuffer( dStrlen( buffer ) + 1 );
|
||||
|
||||
dSprintf( buffer, sizeof( buffer ), "%d %d %d",
|
||||
x86UNIXState->getDesktopSize().x,
|
||||
x86UNIXState->getDesktopSize().y,
|
||||
x86UNIXState->getDesktopBpp() );
|
||||
dStrcpy( returnString, buffer );
|
||||
return( returnString );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Silly Korean registry key checker:
|
||||
//------------------------------------------------------------------------------
|
||||
ConsoleFunction( isKoreanBuild, bool, 1, 1, "isKoreanBuild()" )
|
||||
{
|
||||
Con::printf("WARNING: isKoreanBuild() is unimplemented");
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
int main(S32 argc, const char **argv)
|
||||
{
|
||||
// init platform state
|
||||
x86UNIXState = new x86UNIXPlatformState;
|
||||
|
||||
// parse the command line for unix-specific params
|
||||
Vector<char *> newCommandLine;
|
||||
S32 returnVal = ParseCommandLine(argc, argv, newCommandLine);
|
||||
if (returnVal != 0)
|
||||
return returnVal;
|
||||
|
||||
// init lastTimeTick for TimeManager::process()
|
||||
lastTimeTick = Platform::getRealMilliseconds();
|
||||
|
||||
// init process control stuff
|
||||
ProcessControlInit();
|
||||
|
||||
// check to see if X is running
|
||||
DetectWindowingSystem();
|
||||
|
||||
// run the game
|
||||
returnVal = Game->main(newCommandLine.size(),
|
||||
const_cast<const char**>(newCommandLine.address()));
|
||||
|
||||
// dispose of command line
|
||||
for(U32 i = 0; i < newCommandLine.size(); i++)
|
||||
delete [] newCommandLine[i];
|
||||
|
||||
// dispose of state
|
||||
delete x86UNIXState;
|
||||
|
||||
return returnVal;
|
||||
}
|
Reference in New Issue
Block a user