This commit is contained in:
MarianoGNU 2015-10-17 23:38:33 -03:00
commit 4452e26253
108 changed files with 3000 additions and 335 deletions

5
.gitignore vendored
View File

@ -23,6 +23,9 @@ tools/editor/editor_icons.cpp
make.bat
log.txt
# Doxygen generated documentation
doc/doxygen/*
# Javascript specific
*.bc
@ -81,6 +84,8 @@ platform/android/libs/play_licensing/gen/*
*.suo
*.user
*.sln.docstates
*.sln
*.vcxproj*
# Build results
[Dd]ebug/

View File

@ -51,14 +51,14 @@ PROJECT_BRIEF = "Game Engine MIT"
# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
# the logo to the output directory.
PROJECT_LOGO = E:/development/godot/logo_small.png
PROJECT_LOGO = ./logo_small.png
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
# into which the generated documentation will be written. If a relative path is
# entered, it will be relative to the location where doxygen was started. If
# left blank the current directory will be used.
OUTPUT_DIRECTORY = E:/development/godot/doxygen
OUTPUT_DIRECTORY = ./doc/doxygen/
# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
# directories (in 2 levels) under the output directory of each output format and
@ -768,7 +768,7 @@ WARN_LOGFILE =
# spaces.
# Note: If this tag is empty the current directory is searched.
INPUT = E:/development/godot
INPUT = ./core/ ./main/ ./scene/
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses

View File

@ -61,6 +61,7 @@ const char ** tests_get_names() {
"gui",
"io",
"shaderlang",
"physics",
NULL
};

View File

@ -31,8 +31,7 @@ void FuncRef::_bind_methods() {
{
MethodInfo mi;
mi.name="call";
mi.arguments.push_back( PropertyInfo( Variant::STRING, "method"));
mi.name="call_func";
Vector<Variant> defargs;
for(int i=0;i<10;i++) {
mi.arguments.push_back( PropertyInfo( Variant::NIL, "arg"+itos(i)));

View File

@ -299,10 +299,8 @@ Error decode_variant(Variant& r_variant,const uint8_t *p_buffer, int p_len,int *
ERR_FAIL_COND_V(len<12,ERR_INVALID_DATA);
Vector<StringName> names;
Vector<StringName> subnames;
bool absolute;
StringName prop;
int i=0;
uint32_t namecount=strlen&=0x7FFFFFFF;
uint32_t subnamecount = decode_uint32(buf+4);
uint32_t flags = decode_uint32(buf+8);
@ -391,7 +389,6 @@ Error decode_variant(Variant& r_variant,const uint8_t *p_buffer, int p_len,int *
ie.type=decode_uint32(&buf[0]);
ie.device=decode_uint32(&buf[4]);
uint32_t len = decode_uint32(&buf[8])-12;
if (r_len)
(*r_len)+=12;

View File

@ -231,14 +231,12 @@ Ref<ResourceImportMetadata> ResourceLoader::load_import_metadata(const String &p
local_path = Globals::get_singleton()->localize_path(p_path);
String extension=p_path.extension();
bool found=false;
Ref<ResourceImportMetadata> ret;
for (int i=0;i<loader_count;i++) {
if (!loader[i]->recognize(extension))
continue;
found=true;
Error err = loader[i]->load_import_metadata(local_path,ret);
if (err==OK)

View File

@ -1788,7 +1788,7 @@ extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len)
return UNZ_PARAMERROR;
if ((pfile_in_zip_read_info->read_buffer == NULL))
if (pfile_in_zip_read_info->read_buffer==NULL)
return UNZ_END_OF_LIST_OF_FILE;
if (len==0)
return 0;

View File

@ -1114,9 +1114,9 @@ extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename,
zi->ci.flag = flagBase;
if ((level==8) || (level==9))
zi->ci.flag |= 2;
if ((level==2))
if (level==2)
zi->ci.flag |= 4;
if ((level==1))
if (level==1)
zi->ci.flag |= 6;
if (password != NULL)
zi->ci.flag |= 1;

View File

@ -518,10 +518,16 @@ public:
if (value->prev_ptr) {
value->prev_ptr->next_ptr = value->next_ptr;
};
}
else {
_data->first = value->next_ptr;
}
if (value->next_ptr) {
value->next_ptr->prev_ptr = value->prev_ptr;
};
}
else {
_data->last = value->prev_ptr;
}
value->next_ptr = where;
if (!where) {

View File

@ -40,11 +40,11 @@ struct Vector3 {
enum Axis {
AXIS_X,
AXIS_Y,
AXIS_Z,
AXIS_Z,
};
union {
#ifdef USE_QUAD_VECTORS
struct {
@ -52,7 +52,7 @@ struct Vector3 {
real_t y;
real_t z;
real_t _unused;
};
};
real_t coord[4];
#else
@ -61,18 +61,18 @@ struct Vector3 {
real_t y;
real_t z;
};
real_t coord[3];
#endif
};
_FORCE_INLINE_ const real_t& operator[](int p_axis) const {
return coord[p_axis];
}
_FORCE_INLINE_ real_t& operator[](int p_axis) {
return coord[p_axis];
}
@ -84,7 +84,7 @@ struct Vector3 {
_FORCE_INLINE_ real_t length() const;
_FORCE_INLINE_ real_t length_squared() const;
_FORCE_INLINE_ void normalize();
_FORCE_INLINE_ Vector3 normalized() const;
_FORCE_INLINE_ Vector3 inverse() const;
@ -107,6 +107,8 @@ struct Vector3 {
_FORCE_INLINE_ real_t dot(const Vector3& p_b) const;
_FORCE_INLINE_ Vector3 abs() const;
_FORCE_INLINE_ Vector3 floor() const;
_FORCE_INLINE_ Vector3 ceil() const;
_FORCE_INLINE_ real_t distance_to(const Vector3& p_b) const;
_FORCE_INLINE_ real_t distance_squared_to(const Vector3& p_b) const;
@ -172,7 +174,17 @@ real_t Vector3::dot(const Vector3& p_b) const {
Vector3 Vector3::abs() const {
return Vector3( Math::abs(x), Math::abs(y), Math::abs(z) );
}
}
Vector3 Vector3::floor() const {
return Vector3( Math::floor(x), Math::floor(y), Math::floor(z) );
}
Vector3 Vector3::ceil() const {
return Vector3( Math::ceil(x), Math::ceil(y), Math::ceil(z) );
}
Vector3 Vector3::linear_interpolate(const Vector3& p_b,float p_t) const {
@ -301,7 +313,7 @@ bool Vector3::operator<(const Vector3& p_v) const {
return y<p_v.y;
} else
return x<p_v.x;
}
bool Vector3::operator<=(const Vector3& p_v) const {

View File

@ -3066,7 +3066,7 @@ String String::world_wrap(int p_chars_per_line) const {
} else if (operator[](i)==' ' || operator[](i)=='\t') {
last_space=i;
} else if (operator[](i)=='\n') {
ret+=substr(from,i-from);
ret+=substr(from,i-from)+"\n";
from=i+1;
last_space=-1;
}

View File

@ -359,6 +359,8 @@ static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Var
VCALL_LOCALMEM1R(Vector3, dot);
VCALL_LOCALMEM1R(Vector3, cross);
VCALL_LOCALMEM0R(Vector3, abs);
VCALL_LOCALMEM0R(Vector3, floor);
VCALL_LOCALMEM0R(Vector3, ceil);
VCALL_LOCALMEM1R(Vector3, distance_to);
VCALL_LOCALMEM1R(Vector3, distance_squared_to);
VCALL_LOCALMEM1R(Vector3, slide);
@ -753,7 +755,7 @@ static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Var
}
static void Matrix32_init2(Variant& r_ret,const Variant** p_args) {
Matrix32 m(*p_args[0], *p_args[1]);
r_ret=m;
}
@ -1133,7 +1135,7 @@ void Variant::get_method_list(List<MethodInfo> *p_list) const {
if (fd.returns)
ret.name="ret";
mi.return_val=ret;
#endif
#endif
p_list->push_back(mi);
}
@ -1336,6 +1338,8 @@ _VariantCall::addfunc(Variant::m_vtype,Variant::m_ret,_SCS(#m_method),VCALL(m_cl
ADDFUNC1(VECTOR3,REAL,Vector3,dot,VECTOR3,"b",varray());
ADDFUNC1(VECTOR3,VECTOR3,Vector3,cross,VECTOR3,"b",varray());
ADDFUNC0(VECTOR3,VECTOR3,Vector3,abs,varray());
ADDFUNC0(VECTOR3,VECTOR3,Vector3,floor,varray());
ADDFUNC0(VECTOR3,VECTOR3,Vector3,ceil,varray());
ADDFUNC1(VECTOR3,REAL,Vector3,distance_to,VECTOR3,"b",varray());
ADDFUNC1(VECTOR3,REAL,Vector3,distance_squared_to,VECTOR3,"b",varray());
ADDFUNC1(VECTOR3,VECTOR3,Vector3,slide,VECTOR3,"by",varray());
@ -1535,10 +1539,10 @@ _VariantCall::addfunc(Variant::m_vtype,Variant::m_ret,_SCS(#m_method),VCALL(m_cl
ADDFUNC1(TRANSFORM,NIL,Transform,xform,NIL,"v",varray());
ADDFUNC1(TRANSFORM,NIL,Transform,xform_inv,NIL,"v",varray());
#ifdef DEBUG_ENABLED
#ifdef DEBUG_ENABLED
_VariantCall::type_funcs[Variant::TRANSFORM].functions["xform"].returns=true;
_VariantCall::type_funcs[Variant::TRANSFORM].functions["xform_inv"].returns=true;
#endif
#endif
ADDFUNC0(INPUT_EVENT,BOOL,InputEvent,is_pressed,varray());
ADDFUNC1(INPUT_EVENT,BOOL,InputEvent,is_action,STRING,"action",varray());
@ -1635,9 +1639,3 @@ void unregister_variant_methods() {
}

View File

@ -0,0 +1 @@
filter=false

View File

@ -91,4 +91,5 @@ func _ready():
# Initalization here
pass
func _die():
queue_free()

Binary file not shown.

View File

@ -5905,7 +5905,7 @@
<description>
Base class of anything 2D. Canvas items are laid out in a tree and children inherit and extend the transform of their parent. CanvasItem is extended by [Control], for anything GUI related, and by [Node2D] for anything 2D engine related.
Any CanvasItem can draw. For this, the "update" function must be called, then NOTIFICATION_DRAW will be received on idle time to request redraw. Because of this, canvas items don't need to be redraw on every frame, improving the performance significan'tly. Several functions for drawing on the CanvasItem are provided (see draw_* functions). They can only be used inside the notification, signal or _draw() overrided function, though.
Canvas items are draw in tree order. By default, children are on top of their parents so a root CanvasItem will be drawn behind everything (this can be changed per item though).
Canvas items are draw in tree order. By default, children are on top of their parents so a root CanvasItem will be drawn behind everything (this can be changed per item though).
Canvas items can also be hidden (hiding also their subtree). They provide many means for changing standard parameters such as opacity (for it and the subtree) and self opacity, blend mode.
Ultimately, a transform notification can be requested, which will notify the node that its global position changed in case the parent tree changed.
</description>
@ -11556,8 +11556,11 @@
</class>
<class name="GraphEdit" inherits="Control" category="Core">
<brief_description>
GraphEdit is an area capable of showing various GraphNodes. It manages connection events between them.
</brief_description>
<description>
GraphEdit manages the showing of GraphNodes it contains, as well as connections an disconnections between them. Signals are sent for each of these two events. Disconnection between GraphNodes slots is disabled by default.
It is greatly advised to enable low processor usage mode [OS.set_low_processor_usage_mode()] when using GraphEdits.
</description>
<methods>
<method name="connect_node">
@ -11572,6 +11575,7 @@
<argument index="3" name="to_port" type="int">
</argument>
<description>
Create a connection between 'from_port' slot of 'from' GraphNode and 'to_port' slot of 'to' GraphNode. If the connection already exists, no connection is created.
</description>
</method>
<method name="is_node_connected">
@ -11586,6 +11590,7 @@
<argument index="3" name="to_port" type="int">
</argument>
<description>
Return true if the 'from_port' slot of 'from' GraphNode is connected to the 'to_port' slot of 'to' GraphNode.
</description>
</method>
<method name="disconnect_node">
@ -11598,24 +11603,28 @@
<argument index="3" name="to_port" type="int">
</argument>
<description>
Remove the connection between 'from_port' slot of 'from' GraphNode and 'to_port' slot of 'to' GraphNode, if connection exists.
</description>
</method>
<method name="get_connection_list" qualifiers="const">
<return type="Array">
</return>
<description>
Return an Array containing the list of connections. A connection consists in a structure of the form {from_slot: 0, from: "GraphNode name 0", to_slot: 1, to: "GraphNode name 1" }
</description>
</method>
<method name="set_right_disconnects">
<argument index="0" name="enable" type="bool">
</argument>
<description>
Enable the disconnection of existing connections in the visual GraphEdit by left-clicking a connection and releasing into the void.
</description>
</method>
<method name="is_right_disconnects_enabled" qualifiers="const">
<return type="bool">
</return>
<description>
Return true is the disconnection of connections is enable in the visual GraphEdit. False otherwise.
</description>
</method>
</methods>
@ -11630,6 +11639,7 @@
<argument index="3" name="to_slot" type="int">
</argument>
<description>
Signal sent to the GraphEdit when the connection between 'from_slot' slot of 'from' GraphNode and 'to_slot' slot of 'to' GraphNode is attempted to be removed.
</description>
</signal>
<signal name="connection_request">
@ -11642,6 +11652,7 @@
<argument index="3" name="to_slot" type="int">
</argument>
<description>
Signal sent to the GraphEdit when the connection between 'from_slot' slot of 'from' GraphNode and 'to_slot' slot of 'to' GraphNode is attempted to be created.
</description>
</signal>
</signals>
@ -11650,20 +11661,24 @@
</class>
<class name="GraphNode" inherits="Container" category="Core">
<brief_description>
A GraphNode is a container with several input and output slots allowing connections between GraphNodes. Slots can have different, incompatible types.
</brief_description>
<description>
A GraphNode is a container defined by a title. It can have 1 or more input and output slots, which can be enabled (shown) or disabled (not shown) and have different (incompatible) types. Colors can also be assigned to slots. A tuple of input and output slots is defined for each GUI element included in the GraphNode. Input and output connections are left and right slots, but only enabled slots are counted as connections.
</description>
<methods>
<method name="set_title">
<argument index="0" name="title" type="String">
</argument>
<description>
Set the title of the GraphNode.
</description>
</method>
<method name="get_title" qualifiers="const">
<return type="String">
</return>
<description>
Return the title of the GraphNode.
</description>
</method>
<method name="set_slot">
@ -11682,16 +11697,19 @@
<argument index="6" name="color_right" type="Color">
</argument>
<description>
Set the tuple of input/output slots defined by 'idx' ID. 'left' slots are input, 'right' are output. 'type' is an integer defining the type of the slot. Refer to description for the compatibility between slot types.
</description>
</method>
<method name="clear_slot">
<argument index="0" name="idx" type="int">
</argument>
<description>
Disable input and ouput slot whose index is 'idx'.
</description>
</method>
<method name="clear_all_slots">
<description>
Disable all input and output slots of the GraphNode.
</description>
</method>
<method name="is_slot_enabled_left" qualifiers="const">
@ -11700,6 +11718,7 @@
<argument index="0" name="idx" type="int">
</argument>
<description>
Return true if left (input) slot 'idx' is enabled. False otherwise.
</description>
</method>
<method name="get_slot_type_left" qualifiers="const">
@ -11708,6 +11727,7 @@
<argument index="0" name="idx" type="int">
</argument>
<description>
Return the (integer) type of left (input) 'idx' slot.
</description>
</method>
<method name="get_slot_color_left" qualifiers="const">
@ -11716,6 +11736,7 @@
<argument index="0" name="idx" type="int">
</argument>
<description>
Return the color set to 'idx' left (input) slot.
</description>
</method>
<method name="is_slot_enabled_right" qualifiers="const">
@ -11724,6 +11745,7 @@
<argument index="0" name="idx" type="int">
</argument>
<description>
Return true if right (output) slot 'idx' is enabled. False otherwise.
</description>
</method>
<method name="get_slot_type_right" qualifiers="const">
@ -11732,6 +11754,7 @@
<argument index="0" name="idx" type="int">
</argument>
<description>
Return the (integer) type of right (output) 'idx' slot.
</description>
</method>
<method name="get_slot_color_right" qualifiers="const">
@ -11740,30 +11763,35 @@
<argument index="0" name="idx" type="int">
</argument>
<description>
Return the color set to 'idx' right (output) slot.
</description>
</method>
<method name="set_offset">
<argument index="0" name="offset" type="Vector2">
</argument>
<description>
Set the offset of the GraphNode.
</description>
</method>
<method name="get_offset" qualifiers="const">
<return type="Vector2">
</return>
<description>
Return the offset of the GraphNode.
</description>
</method>
<method name="get_connection_output_count">
<return type="int">
</return>
<description>
Return the number of enabled output slots (connections) of the GraphNode.
</description>
</method>
<method name="get_connection_input_count">
<return type="int">
</return>
<description>
Return the number of enabled input slots (connections) to the GraphNode.
</description>
</method>
<method name="get_connection_output_pos">
@ -11772,6 +11800,7 @@
<argument index="0" name="idx" type="int">
</argument>
<description>
Return the position of the output connection 'idx'.
</description>
</method>
<method name="get_connection_output_type">
@ -11780,6 +11809,7 @@
<argument index="0" name="idx" type="int">
</argument>
<description>
Return the type of the output connection 'idx'.
</description>
</method>
<method name="get_connection_output_color">
@ -11788,6 +11818,7 @@
<argument index="0" name="idx" type="int">
</argument>
<description>
Return the color of the output connection 'idx'.
</description>
</method>
<method name="get_connection_input_pos">
@ -11796,6 +11827,7 @@
<argument index="0" name="idx" type="int">
</argument>
<description>
Return the position of the input connection 'idx'.
</description>
</method>
<method name="get_connection_input_type">
@ -11804,6 +11836,7 @@
<argument index="0" name="idx" type="int">
</argument>
<description>
Return the type of the input connection 'idx'.
</description>
</method>
<method name="get_connection_input_color">
@ -11812,28 +11845,33 @@
<argument index="0" name="idx" type="int">
</argument>
<description>
Return the color of the input connection 'idx'.
</description>
</method>
<method name="set_show_close_button">
<argument index="0" name="show" type="bool">
</argument>
<description>
Show the close button on the GraphNode if 'show' is true (disabled by default). If enabled, a connection on the signal close_request is needed for the close button to work.
</description>
</method>
<method name="is_close_button_visible" qualifiers="const">
<return type="bool">
</return>
<description>
Returns true if the close button is shown. False otherwise.
</description>
</method>
</methods>
<signals>
<signal name="raise_request">
<description>
Signal sent when the GraphNode is requested to be displayed over other ones. Happens on focusing (clicking into) the GraphNode.
</description>
</signal>
<signal name="close_request">
<description>
Signal sent on closing the GraphNode.
</description>
</signal>
<signal name="dragged">
@ -11842,10 +11880,12 @@
<argument index="1" name="to" type="Vector2">
</argument>
<description>
Signal sent when the GraphNode is dragged.
</description>
</signal>
<signal name="offset_changed">
<description>
Signal sent when the GraphNode is moved.
</description>
</signal>
</signals>
@ -17934,7 +17974,7 @@
</brief_description>
<description>
Nodes can be set as children of other nodes, resulting in a tree arrangement. Any tree of nodes is called a "Scene".
Scenes can be saved to disk, and then instanced into other scenes. This allows for very high flexibility in the architecture and data model of the projects.
Scenes can be saved to disk, and then instanced into other scenes. This allows for very high flexibility in the architecture and data model of the projects.
[SceneMainLoop] contains the "active" tree of nodes, and a node becomes active (receinving NOTIFICATION_ENTER_SCENE) when added to that tree.
A node can contain any number of nodes as a children (but there is only one tree root) with the requirement that no two childrens with the same name can exist.
Nodes can, optionally, be added to groups. This makes it easy to reach a number of nodes from the code (for example an "enemies" group).
@ -18684,11 +18724,11 @@
<description>
Operating System functions. OS Wraps the most common functionality to communicate with the host Operating System, such as:
-Mouse Grabbing
-Mouse Cursors
-Mouse Cursors
-Clipboard
-Video Mode
-Date " Time
-Timers
-Timers
-Environment Variables
-Execution of Binaries
-Command Line
@ -27567,7 +27607,7 @@
Rigid body 2D node.
</brief_description>
<description>
Rigid body 2D node. This node is used for placing rigid bodies in the scene. It can contain a number of shapes, and also shift state between regular Rigid Body to Character or even Static.
Rigid body 2D node. This node is used for placing rigid bodies in the scene. It can contain a number of shapes, and also shift state between regular Rigid Body to Character or even Static.
Character mode forbids the node from being rotated. This node can have a custom force integrator function, for writing complex physics motion behavior per node.
As a warning, don't change this node position every frame or very often. Sporadic changes work fine, but physics runs at a different granularity (fixed hz) than usual rendering (process callback) and maybe even in a separate thread, so changing this from a process loop will yield strange behavior.
</description>
@ -37719,6 +37759,18 @@
<description>
</description>
</method>
<method name="set_audio_track">
<argument index="0" name="track" type="int">
</argument>
<description>
</description>
</method>
<method name="get_audio_track" qualifiers="const">
<return type="int">
</return>
<description>
</description>
</method>
<method name="get_stream_name" qualifiers="const">
<return type="String">
</return>
@ -37755,6 +37807,18 @@
<description>
</description>
</method>
<method name="set_buffering_msec">
<argument index="0" name="msec" type="int">
</argument>
<description>
</description>
</method>
<method name="get_buffering_msec" qualifiers="const">
<return type="int">
</return>
<description>
</description>
</method>
</methods>
<constants>
</constants>
@ -37765,30 +37829,16 @@
<description>
</description>
<methods>
<method name="get_pending_frame_count" qualifiers="const">
<return type="int">
</return>
<description>
</description>
</method>
<method name="pop_frame">
<argument index="0" name="arg0" type="Object">
</argument>
<description>
</description>
</method>
<method name="peek_frame" qualifiers="const">
<return type="Image">
</return>
<description>
</description>
</method>
<method name="set_audio_track">
<argument index="0" name="idx" type="int">
</argument>
<description>
</description>
</method>
</methods>
<constants>
</constants>
</class>
<class name="VideoStreamTheora" inherits="VideoStream" category="Core">
<brief_description>
</brief_description>
<description>
</description>
<methods>
</methods>
<constants>
</constants>

View File

@ -1,3 +1,7 @@
#ifdef __HAIKU__
#undef GLEW_ENABLED
#endif
#ifdef GLEW_ENABLED
/*
** The OpenGL Extension Wrangler Library

View File

@ -243,7 +243,7 @@ OS::Date OS_Unix::get_date(bool utc) const {
lt=localtime(&t);
Date ret;
ret.year=1900+lt->tm_year;
ret.month=(Month)lt->tm_mon;
ret.month=(Month)(lt->tm_mon + 1);
ret.day=lt->tm_mday;
ret.weekday=(Weekday)lt->tm_wday;
ret.dst=lt->tm_isdst;

View File

@ -13,7 +13,11 @@
#include <stdio.h>
#ifndef NO_FCNTL
#include <sys/fcntl.h>
#ifdef __HAIKU__
#include <fcntl.h>
#else
#include <sys/fcntl.h>
#endif
#else
#include <sys/ioctl.h>
#endif

View File

@ -39,7 +39,11 @@
#include <netdb.h>
#include <sys/types.h>
#ifndef NO_FCNTL
#include <sys/fcntl.h>
#ifdef __HAIKU__
#include <fcntl.h>
#else
#include <sys/fcntl.h>
#endif
#else
#include <sys/ioctl.h>
#endif

View File

@ -41,7 +41,11 @@
#include <netdb.h>
#include <sys/types.h>
#ifndef NO_FCNTL
#include <sys/fcntl.h>
#ifdef __HAIKU__
#include <fcntl.h>
#else
#include <sys/fcntl.h>
#endif
#else
#include <sys/ioctl.h>
#endif

View File

@ -29,7 +29,7 @@ extern "C" {
#define WEBP_USE_SSE2
#endif
#if defined(__ANDROID__) && defined(__ARM_ARCH_7A__)
#if defined(__ANDROID__) && defined(__ARM_ARCH_7A__) && defined(__ARM_NEON__)
#define WEBP_ANDROID_NEON // Android targets that might support NEON
#endif

View File

@ -1007,61 +1007,49 @@ bool Main::start() {
bool export_debug=false;
List<String> args = OS::get_singleton()->get_cmdline_args();
for (int i=0;i<args.size();i++) {
if (args[i]=="-doctool" && i <(args.size()-1)) {
doc_tool=args[i+1];
//parameters that have an argument to the right
if (i < (args.size()-1)) {
if (args[i]=="-doctool") {
doc_tool=args[i+1];
} else if (args[i]=="-script" || args[i]=="-s") {
script=args[i+1];
} else if (args[i]=="-level" || args[i]=="-l") {
OS::get_singleton()->_custom_level=args[i+1];
} else if (args[i]=="-test") {
test=args[i+1];
} else if (args[i]=="-optimize") {
optimize=args[i+1];
} else if (args[i]=="-optimize_preset") {
optimize_preset=args[i+1];
} else if (args[i]=="-export") {
editor=true; //needs editor
_export_platform=args[i+1];
} else if (args[i]=="-export_debug") {
editor=true; //needs editor
_export_platform=args[i+1];
export_debug=true;
} else if (args[i]=="-import") {
editor=true; //needs editor
_import=args[i+1];
} else if (args[i]=="-import_script") {
editor=true; //needs editor
_import_script=args[i+1];
} else if (args[i]=="-dumpstrings") {
editor=true; //needs editor
dumpstrings=args[i+1];
}
i++;
}else if (args[i]=="-nodocbase") {
}
//parameters that do not have an argument to the right
if (args[i]=="-nodocbase") {
doc_base=false;
} else if ((args[i]=="-script" || args[i]=="-s") && i <(args.size()-1)) {
script=args[i+1];
i++;
} else if ((args[i]=="-level" || args[i]=="-l") && i <(args.size()-1)) {
OS::get_singleton()->_custom_level=args[i+1];
i++;
} else if (args[i]=="-test" && i <(args.size()-1)) {
test=args[i+1];
i++;
} else if (args[i]=="-optimize" && i <(args.size()-1)) {
optimize=args[i+1];
i++;
} else if (args[i]=="-optimize_preset" && i <(args.size()-1)) {
optimize_preset=args[i+1];
i++;
} else if (args[i]=="-export" && i <(args.size()-1)) {
editor=true; //needs editor
_export_platform=args[i+1];
i++;
} else if (args[i]=="-export_debug" && i <(args.size()-1)) {
editor=true; //needs editor
_export_platform=args[i+1];
export_debug=true;
i++;
} else if (args[i]=="-import" && i <(args.size()-1)) {
editor=true; //needs editor
_import=args[i+1];
i++;
} else if (args[i]=="-import_script" && i <(args.size()-1)) {
editor=true; //needs editor
_import_script=args[i+1];
i++;
} else if (args[i]=="-noquit" ) {
} else if (args[i]=="-noquit") {
noquit=true;
} else if (args[i]=="-dumpstrings" && i <(args.size()-1)) {
editor=true; //needs editor
dumpstrings=args[i+1];
i++;
} else if (args[i]=="-editor" || args[i]=="-e") {
editor=true;
} else if (args[i]=="-convert_old") {
convert_old=true;
} else if (args[i]=="-editor" || args[i]=="-e") {
editor=true;
} else if (args[i].length() && args[i][0] != '-' && game_path == "") {
game_path=args[i];
}
}
@ -1556,9 +1544,9 @@ bool Main::iteration() {
OS::get_singleton()->delay_usec( OS::get_singleton()->get_frame_delay()*1000 );
}
int taret_fps = OS::get_singleton()->get_target_fps();
if (taret_fps>0) {
uint64_t time_step = 1000000L/taret_fps;
int target_fps = OS::get_singleton()->get_target_fps();
if (target_fps>0) {
uint64_t time_step = 1000000L/target_fps;
target_ticks += time_step;
uint64_t current_ticks = OS::get_singleton()->get_ticks_usec();
if (current_ticks<target_ticks) OS::get_singleton()->delay_usec(target_ticks-current_ticks);

View File

@ -904,6 +904,15 @@ void GDFunctions::call(Function p_func,const Variant **p_args,int p_arg_count,Va
r_ret = gdscr->_new(NULL,0,r_error);
GDInstance *ins = static_cast<GDInstance*>(static_cast<Object*>(r_ret)->get_script_instance());
Ref<GDScript> gd_ref = ins->get_script();
for(Map<StringName,GDScript::MemberInfo>::Element *E = gd_ref->member_indices.front(); E; E = E->next()) {
if(d.has(E->key())) {
ins->members[E->get().index] = d[E->key()];
}
}
} break;
case HASH: {

View File

@ -2421,6 +2421,16 @@ void GDParser::_parse_class(ClassNode *p_class) {
}; //fallthrough to use the same
case Variant::REAL: {
if (tokenizer->get_token()==GDTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier()=="EASE") {
current_export.hint=PROPERTY_HINT_EXP_EASING;
tokenizer->advance();
if (tokenizer->get_token()!=GDTokenizer::TK_PARENTHESIS_CLOSE) {
_set_error("Expected ')' in hint.");
return;
}
break;
}
float sign=1.0;
if (tokenizer->get_token()==GDTokenizer::TK_OP_SUB) {
@ -2571,6 +2581,17 @@ void GDParser::_parse_class(ClassNode *p_class) {
}
break;
}
if (tokenizer->get_token()==GDTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier()=="MULTILINE") {
current_export.hint=PROPERTY_HINT_MULTILINE_TEXT;
tokenizer->advance();
if (tokenizer->get_token()!=GDTokenizer::TK_PARENTHESIS_CLOSE) {
_set_error("Expected ')' in hint.");
return;
}
break;
}
} break;
case Variant::COLOR: {
@ -2607,23 +2628,16 @@ void GDParser::_parse_class(ClassNode *p_class) {
} else if (tokenizer->get_token()==GDTokenizer::TK_IDENTIFIER) {
String identifier = tokenizer->get_token_identifier();
if (identifier == "flag") {
current_export.type=Variant::INT;
current_export.hint=PROPERTY_HINT_ALL_FLAGS;
}else if (identifier == "multiline"){
current_export.type=Variant::STRING;
current_export.hint=PROPERTY_HINT_MULTILINE_TEXT;
} else {
if (!ObjectTypeDB::is_type(identifier,"Resource")) {
current_export=PropertyInfo();
_set_error("Export hint not a type or resource.");
}
current_export.type=Variant::OBJECT;
current_export.hint=PROPERTY_HINT_RESOURCE_TYPE;
current_export.hint_string=identifier;
if (!ObjectTypeDB::is_type(identifier,"Resource")) {
current_export=PropertyInfo();
_set_error("Export hint not a type or resource.");
}
current_export.type=Variant::OBJECT;
current_export.hint=PROPERTY_HINT_RESOURCE_TYPE;
current_export.hint_string=identifier;
tokenizer->advance();
}

View File

@ -220,7 +220,9 @@ void GridMapEditor::_menu_option(int p_option) {
} break;
case MENU_OPTION_GRIDMAP_SETTINGS: {
settings_dialog->popup_centered(settings_vbc->get_combined_minimum_size() + Size2(50, 50));
} break;
}
}
@ -304,7 +306,7 @@ bool GridMapEditor::do_input_action(Camera* p_camera,const Point2& p_point,bool
p.d=edit_floor[edit_axis]*node->get_cell_size();
Vector3 inters;
if (!p.intersects_segment(from,from+normal*500,&inters))
if (!p.intersects_segment(from, from + normal * settings_pick_distance->get_val(), &inters))
return false;
@ -1249,6 +1251,24 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
//options->get_popup()->add_separator();
//options->get_popup()->add_item("Configure",MENU_OPTION_CONFIGURE);
options->get_popup()->add_separator();
options->get_popup()->add_item("Settings", MENU_OPTION_GRIDMAP_SETTINGS);
settings_dialog = memnew(ConfirmationDialog);
settings_dialog->set_title("GridMap Settings");
add_child(settings_dialog);
settings_vbc = memnew(VBoxContainer);
settings_vbc->set_custom_minimum_size(Size2(200, 0));
settings_dialog->add_child(settings_vbc);
settings_dialog->set_child_rect(settings_vbc);
settings_pick_distance = memnew(SpinBox);
settings_pick_distance->set_max(10000.0f);
settings_pick_distance->set_min(500.0f);
settings_pick_distance->set_step(1.0f);
settings_pick_distance->set_val(EDITOR_DEF("gridmap_editor/pick_distance", 5000.0));
settings_vbc->add_margin_child("Pick Distance:", settings_pick_distance);
clip_mode=CLIP_DISABLED;
options->get_popup()->connect("item_pressed", this,"_menu_option");

View File

@ -78,6 +78,9 @@ class GridMapEditor : public VBoxContainer {
ToolButton *mode_thumbnail;
ToolButton *mode_list;
HBoxContainer *spatial_editor_hb;
ConfirmationDialog *settings_dialog;
VBoxContainer *settings_vbc;
SpinBox *settings_pick_distance;
struct SetItem {
@ -165,8 +168,8 @@ class GridMapEditor : public VBoxContainer {
MENU_OPTION_SELECTION_MAKE_AREA,
MENU_OPTION_SELECTION_MAKE_EXTERIOR_CONNECTOR,
MENU_OPTION_SELECTION_CLEAR,
MENU_OPTION_REMOVE_AREA
MENU_OPTION_REMOVE_AREA,
MENU_OPTION_GRIDMAP_SETTINGS
};

View File

@ -236,13 +236,12 @@ void AudioDriverOpenSL::start(){
ERR_FAIL_COND( res !=SL_RESULT_SUCCESS );
/* Initialize arrays required[] and iidArray[] */
int i;
SLboolean required[MAX_NUMBER_INTERFACES];
SLInterfaceID iidArray[MAX_NUMBER_INTERFACES];
#if 0
for (i=0; i<MAX_NUMBER_INTERFACES; i++)
for (int i=0; i<MAX_NUMBER_INTERFACES; i++)
{
required[i] = SL_BOOLEAN_FALSE;
iidArray[i] = SL_IID_NULL;

View File

@ -127,7 +127,7 @@ static __inline__ void x86_cpuid(int func, int values[4])
static int
get_file_size(const char* pathname)
{
int fd, ret, result = 0;
int fd, result = 0;
char buffer[256];
fd = open(pathname, O_RDONLY);

View File

@ -20,15 +20,14 @@ def can_build():
def get_opts():
return [
('ANDROID_NDK_ROOT', 'the path to Android NDK', os.environ.get("ANDROID_NDK_ROOT", 0)),
('NDK_TOOLCHAIN', 'toolchain to use for the NDK',"arm-eabi-4.4.0"),
#android 2.3
('ndk_platform', 'compile for platform: (2.2,2.3)',"2.2"),
('NDK_TARGET', 'toolchain to use for the NDK',"arm-linux-androideabi-4.8"),
('android_stl','enable STL support in android port (for modules)','no'),
('armv6','compile for older phones running arm v6 (instead of v7+neon+smp)','no'),
('x86','Xompile for Android-x86','no')
('ANDROID_NDK_ROOT', 'the path to Android NDK', os.environ.get("ANDROID_NDK_ROOT", 0)),
('NDK_TOOLCHAIN', 'toolchain to use for the NDK',"arm-eabi-4.4.0"),
('NDK_TARGET', 'toolchain to use for the NDK',"arm-linux-androideabi-4.8"),
('NDK_TARGET_X86', 'toolchain to use for the NDK x86',"x86-4.8"),
('ndk_platform', 'compile for platform: (android-<api> , example: android-15)',"android-15"),
('android_arch', 'select compiler architecture: (armv7/armv6/x86)',"armv7"),
('android_neon','enable neon (armv7 only)',"yes"),
('android_stl','enable STL support in android port (for modules)',"no")
]
def get_flags():
@ -92,8 +91,13 @@ def configure(env):
env['SPAWN'] = mySpawn
if env['x86']=='yes':
env['NDK_TARGET']='x86-4.8'
ndk_platform=env['ndk_platform']
if env['android_arch'] not in ['armv7','armv6','x86']:
env['android_arch']='armv7'
if env['android_arch']=='x86':
env['NDK_TARGET']=env['NDK_TARGET_X86']
if env['PLATFORM'] == 'win32':
import methods
@ -101,22 +105,28 @@ def configure(env):
#env['SPAWN'] = methods.win32_spawn
env['SHLIBSUFFIX'] = '.so'
# env.android_source_modules.append("../libs/apk_expansion")
#env.android_source_modules.append("../libs/apk_expansion")
env.android_source_modules.append("../libs/google_play_services")
env.android_source_modules.append("../libs/downloader_library")
env.android_source_modules.append("../libs/play_licensing")
ndk_platform=""
ndk_platform="android-15"
print("Godot Android!!!!!")
neon_text=""
if env["android_arch"]=="armv7" and env['android_neon']=='yes':
neon_text=" (with neon)"
print("Godot Android!!!!! ("+env['android_arch']+")"+neon_text)
env.Append(CPPPATH=['#platform/android'])
if env['x86']=='yes':
env.extra_suffix=".x86"
if env['android_arch']=='x86':
env.extra_suffix=".x86"+env.extra_suffix
elif env['android_arch']=='armv6':
env.extra_suffix=".armv6"+env.extra_suffix
elif env["android_arch"]=="armv7":
if env['android_neon']=='yes':
env.extra_suffix=".armv7.neon"+env.extra_suffix
else:
env.extra_suffix=".armv7"+env.extra_suffix
gcc_path=env["ANDROID_NDK_ROOT"]+"/toolchains/"+env["NDK_TARGET"]+"/prebuilt/";
import os
@ -134,7 +144,7 @@ def configure(env):
env['ENV']['PATH'] = gcc_path+":"+env['ENV']['PATH']
if env['x86']=='yes':
if env['android_arch']=='x86':
env['CC'] = gcc_path+'/i686-linux-android-gcc'
env['CXX'] = gcc_path+'/i686-linux-android-g++'
env['AR'] = gcc_path+"/i686-linux-android-ar"
@ -147,7 +157,7 @@ def configure(env):
env['RANLIB'] = gcc_path+"/arm-linux-androideabi-ranlib"
env['AS'] = gcc_path+"/arm-linux-androideabi-as"
if env['x86']=='yes':
if env['android_arch']=='x86':
env['ARCH'] = 'arch-x86'
else:
env['ARCH'] = 'arch-arm'
@ -161,12 +171,18 @@ def configure(env):
env.Append(CPPPATH=[gcc_include])
# env['CCFLAGS'] = string.split('-DNO_THREADS -MMD -MP -MF -fpic -ffunction-sections -funwind-tables -fstack-protector -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ -Wno-psabi -march=armv5te -mtune=xscale -msoft-float -fno-exceptions -mthumb -fno-strict-aliasing -DANDROID -Wa,--noexecstack -DGLES2_ENABLED ')
if env['x86']=='yes':
env['neon_enabled']=False
if env['android_arch']=='x86':
env['CCFLAGS'] = string.split('-DNO_STATVFS -MMD -MP -MF -fpic -ffunction-sections -funwind-tables -fstack-protector -fvisibility=hidden -D__GLIBC__ -Wno-psabi -ftree-vectorize -funsafe-math-optimizations -fno-strict-aliasing -DANDROID -Wa,--noexecstack -DGLES2_ENABLED')
elif env["armv6"]!="no":
elif env["android_arch"]=="armv6":
env['CCFLAGS'] = string.split('-DNO_STATVFS -MMD -MP -MF -fpic -ffunction-sections -funwind-tables -fstack-protector -fvisibility=hidden -D__ARM_ARCH_6__ -D__GLIBC__ -Wno-psabi -march=armv6 -mfpu=vfp -mfloat-abi=softfp -funsafe-math-optimizations -fno-strict-aliasing -DANDROID -Wa,--noexecstack -DGLES2_ENABLED')
else:
env['CCFLAGS'] = string.split('-DNO_STATVFS -MMD -MP -MF -fpic -ffunction-sections -funwind-tables -fstack-protector -fvisibility=hidden -D__ARM_ARCH_7__ -D__GLIBC__ -Wno-psabi -march=armv6 -mfpu=neon -mfloat-abi=softfp -ftree-vectorize -funsafe-math-optimizations -fno-strict-aliasing -DANDROID -Wa,--noexecstack -DGLES2_ENABLED')
elif env["android_arch"]=="armv7":
env['CCFLAGS'] = string.split('-DNO_STATVFS -MMD -MP -MF -fpic -ffunction-sections -funwind-tables -fstack-protector -fvisibility=hidden -D__ARM_ARCH_7__ -D__ARM_ARCH_7A__ -D__GLIBC__ -Wno-psabi -march=armv7-a -mfloat-abi=softfp -ftree-vectorize -funsafe-math-optimizations -fno-strict-aliasing -DANDROID -Wa,--noexecstack -DGLES2_ENABLED')
if env['android_neon']=='yes':
env['neon_enabled']=True
env.Append(CCFLAGS=['-mfpu=neon','-D__ARM_NEON__'])
else:
env.Append(CCFLAGS=['-mfpu=vfpv3-d16'])
env.Append(LDPATH=[ld_path])
env.Append(LIBS=['OpenSLES'])
@ -190,9 +206,6 @@ def configure(env):
env.Append(CCFLAGS=['-D_DEBUG', '-g1', '-Wall', '-O0', '-DDEBUG_ENABLED'])
env.Append(CPPFLAGS=['-DDEBUG_MEMORY_ALLOC'])
if env["armv6"] == "no" and env['x86'] != 'yes':
env['neon_enabled']=True
env.Append(CPPFLAGS=['-DANDROID_ENABLED', '-DUNIX_ENABLED', '-DNO_FCNTL','-DMPC_FIXED_POINT'])
# env.Append(CPPFLAGS=['-DANDROID_ENABLED', '-DUNIX_ENABLED','-DMPC_FIXED_POINT'])
@ -202,9 +215,17 @@ def configure(env):
if (env['android_stl']=='yes'):
#env.Append(CCFLAGS=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/system/include"])
env.Append(CPPPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gnu-libstdc++/4.4.3/include"])
env.Append(CPPPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gnu-libstdc++/4.4.3/libs/armeabi/include"])
env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gnu-libstdc++/4.4.3/libs/armeabi"])
env.Append(CPPPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gnu-libstdc++/4.8/include"])
if env['android_arch']=='x86':
env.Append(CPPPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gnu-libstdc++/4.8/libs/x86/include"])
env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gnu-libstdc++/4.8/libs/x86"])
elif env['android_arch']=='armv6':
env.Append(CPPPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gnu-libstdc++/4.8/libs/armeabi/include"])
env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gnu-libstdc++/4.8/libs/armeabi"])
elif env["android_arch"]=="armv7":
env.Append(CPPPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gnu-libstdc++/4.8/libs/armeabi-v7a/include"])
env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gnu-libstdc++/4.8/libs/armeabi-v7a"])
env.Append(LIBS=["gnustl_static","supc++"])
env.Append(CPPPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cpufeatures"])
@ -215,10 +236,12 @@ def configure(env):
env.Append(CPPPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gabi++/include"])
env.Append(CPPPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cpufeatures"])
if env['x86']=='yes':
if env['android_arch']=='x86':
env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gabi++/libs/x86"])
else:
elif env["android_arch"]=="armv6":
env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gabi++/libs/armeabi"])
elif env["android_arch"]=="armv7":
env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gabi++/libs/armeabi-v7a"])
env.Append(LIBS=['gabi++_static'])
env.Append(CCFLAGS=["-fno-exceptions",'-DNO_SAFE_CAST'])

View File

@ -47,8 +47,10 @@ public class PaymentsManager {
}
public PaymentsManager initService(){
Intent intent = new Intent("com.android.vending.billing.InAppBillingService.BIND");
intent.setPackage("com.android.vending");
activity.bindService(
new Intent("com.android.vending.billing.InAppBillingService.BIND"),
intent,
mServiceConn,
Context.BIND_AUTO_CREATE);
return this;

View File

@ -1,6 +0,0 @@
/** Automatically generated file. DO NOT MODIFY */
package com.android.vending.expansion.downloader;
public final class BuildConfig {
public final static boolean DEBUG = false;
}

View File

@ -1,73 +0,0 @@
/* AUTO-GENERATED FILE. DO NOT MODIFY.
*
* This class was automatically generated by the
* aapt tool from the resource data it found. It
* should not be modified by hand.
*/
package com.android.vending.expansion.downloader;
public final class R {
public static final class attr {
}
public static final class drawable {
public static int notify_panel_notification_icon_bg=0x7f020000;
}
public static final class id {
public static int appIcon=0x7f060001;
public static int description=0x7f060007;
public static int notificationLayout=0x7f060000;
public static int progress_bar=0x7f060006;
public static int progress_bar_frame=0x7f060005;
public static int progress_text=0x7f060002;
public static int time_remaining=0x7f060004;
public static int title=0x7f060003;
}
public static final class layout {
public static int status_bar_ongoing_event_progress_bar=0x7f030000;
}
public static final class string {
public static int kilobytes_per_second=0x7f040014;
/** When a download completes, a notification is displayed, and this
string is used to indicate that the download successfully completed.
Note that such a download could have been initiated by a variety of
applications, including (but not limited to) the browser, an email
application, a content marketplace.
*/
public static int notification_download_complete=0x7f040000;
/** When a download completes, a notification is displayed, and this
string is used to indicate that the download failed.
Note that such a download could have been initiated by a variety of
applications, including (but not limited to) the browser, an email
application, a content marketplace.
*/
public static int notification_download_failed=0x7f040001;
public static int state_completed=0x7f040007;
public static int state_connecting=0x7f040005;
public static int state_downloading=0x7f040006;
public static int state_failed=0x7f040013;
public static int state_failed_cancelled=0x7f040012;
public static int state_failed_fetching_url=0x7f040010;
public static int state_failed_sdcard_full=0x7f040011;
public static int state_failed_unlicensed=0x7f04000f;
public static int state_fetching_url=0x7f040004;
public static int state_idle=0x7f040003;
public static int state_paused_by_request=0x7f04000a;
public static int state_paused_network_setup_failure=0x7f040009;
public static int state_paused_network_unavailable=0x7f040008;
public static int state_paused_roaming=0x7f04000d;
public static int state_paused_sdcard_unavailable=0x7f04000e;
public static int state_paused_wifi_disabled=0x7f04000c;
public static int state_paused_wifi_unavailable=0x7f04000b;
public static int state_unknown=0x7f040002;
public static int time_remaining=0x7f040015;
public static int time_remaining_notification=0x7f040016;
}
public static final class style {
public static int ButtonBackground=0x7f050003;
public static int NotificationText=0x7f050000;
public static int NotificationTextSecondary=0x7f050004;
public static int NotificationTextShadow=0x7f050001;
public static int NotificationTitle=0x7f050002;
}
}

View File

@ -53,7 +53,6 @@ Error AudioDriverBB10::init(const char* p_name) {
dev_name = (char *) p_name;
}
printf("******** reconnecting to device %s\n", dev_name);
int card, dev;
int ret = snd_pcm_open_name(&pcm_handle, dev_name, SND_PCM_OPEN_PLAYBACK);
ERR_FAIL_COND_V(ret < 0, FAILED);
pcm_open = true;

16
platform/haiku/SCsub Normal file
View File

@ -0,0 +1,16 @@
Import('env')
common_haiku = [
'os_haiku.cpp',
'context_gl_haiku.cpp',
'haiku_application.cpp',
'haiku_direct_window.cpp',
'haiku_gl_view.cpp',
'key_mapping_haiku.cpp',
'audio_driver_media_kit.cpp'
]
env.Program(
'#bin/godot',
['godot_haiku.cpp'] + common_haiku
)

View File

@ -0,0 +1,143 @@
/*************************************************************************/
/* audio_driver_media_kit.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* 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 THE AUTHORS OR COPYRIGHT HOLDERS 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. */
/*************************************************************************/
#include "audio_driver_media_kit.h"
#ifdef MEDIA_KIT_ENABLED
#include "globals.h"
int32_t* AudioDriverMediaKit::samples_in = NULL;
Error AudioDriverMediaKit::init() {
active = false;
mix_rate = 44100;
output_format = OUTPUT_STEREO;
channels = 2;
int latency = GLOBAL_DEF("audio/output_latency", 25);
buffer_size = nearest_power_of_2(latency * mix_rate / 1000);
samples_in = memnew_arr(int32_t, buffer_size * channels);
media_raw_audio_format format;
format = media_raw_audio_format::wildcard;
format.frame_rate = mix_rate;
format.channel_count = channels;
format.format = media_raw_audio_format::B_AUDIO_INT;
format.byte_order = B_MEDIA_LITTLE_ENDIAN;
format.buffer_size = buffer_size * sizeof(int32_t) * channels;
player = new BSoundPlayer(
&format,
"godot_sound_server",
AudioDriverMediaKit::PlayBuffer,
NULL,
this
);
if (player->InitCheck() != B_OK) {
fprintf(stderr, "MediaKit ERR: can not create a BSoundPlayer instance\n");
ERR_FAIL_COND_V(player == NULL, ERR_CANT_OPEN);
}
mutex = Mutex::create();
player->Start();
return OK;
}
void AudioDriverMediaKit::PlayBuffer(void* cookie, void* buffer, size_t size, const media_raw_audio_format& format) {
AudioDriverMediaKit* ad = (AudioDriverMediaKit*) cookie;
int32_t* buf = (int32_t*) buffer;
if (!ad->active) {
for (unsigned int i = 0; i < ad->buffer_size * ad->channels; i++) {
AudioDriverMediaKit::samples_in[i] = 0;
}
} else {
ad->lock();
ad->audio_server_process(ad->buffer_size, AudioDriverMediaKit::samples_in);
ad->unlock();
}
for (unsigned int i = 0; i < ad->buffer_size * ad->channels; i++) {
buf[i] = AudioDriverMediaKit::samples_in[i];
}
}
void AudioDriverMediaKit::start() {
active = true;
}
int AudioDriverMediaKit::get_mix_rate() const {
return mix_rate;
}
AudioDriverSW::OutputFormat AudioDriverMediaKit::get_output_format() const {
return output_format;
}
void AudioDriverMediaKit::lock() {
if (!mutex)
return;
mutex->lock();
}
void AudioDriverMediaKit::unlock() {
if (!mutex)
return;
mutex->unlock();
}
void AudioDriverMediaKit::finish() {
if (player)
delete player;
if (samples_in) {
memdelete_arr(samples_in);
};
if (mutex) {
memdelete(mutex);
mutex = NULL;
}
}
AudioDriverMediaKit::AudioDriverMediaKit() {
mutex = NULL;
player = NULL;
}
AudioDriverMediaKit::~AudioDriverMediaKit() {
}
#endif

View File

@ -0,0 +1,72 @@
/*************************************************************************/
/* audio_driver_media_kit.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* 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 THE AUTHORS OR COPYRIGHT HOLDERS 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. */
/*************************************************************************/
#include "servers/audio/audio_server_sw.h"
#ifdef MEDIA_KIT_ENABLED
#include "core/os/thread.h"
#include "core/os/mutex.h"
#include <kernel/image.h> // needed for image_id
#include <SoundPlayer.h>
class AudioDriverMediaKit : public AudioDriverSW {
Mutex* mutex;
BSoundPlayer* player;
static int32_t* samples_in;
static void PlayBuffer(void* cookie, void* buffer, size_t size, const media_raw_audio_format& format);
unsigned int mix_rate;
OutputFormat output_format;
unsigned int buffer_size;
int channels;
bool active;
public:
const char* get_name() const {
return "MediaKit";
};
virtual Error init();
virtual void start();
virtual int get_mix_rate() const;
virtual OutputFormat get_output_format() const;
virtual void lock();
virtual void unlock();
virtual void finish();
AudioDriverMediaKit();
~AudioDriverMediaKit();
};
#endif

View File

@ -0,0 +1,43 @@
#include "context_gl_haiku.h"
#if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED)
ContextGL_Haiku::ContextGL_Haiku(HaikuDirectWindow* p_window) {
window = p_window;
uint32 type = BGL_RGB | BGL_DOUBLE | BGL_DEPTH;
view = new HaikuGLView(window->Bounds(), type);
}
ContextGL_Haiku::~ContextGL_Haiku() {
delete view;
}
Error ContextGL_Haiku::initialize() {
window->AddChild(view);
window->SetHaikuGLView(view);
return OK;
}
void ContextGL_Haiku::release_current() {
view->UnlockGL();
}
void ContextGL_Haiku::make_current() {
view->LockGL();
}
void ContextGL_Haiku::swap_buffers() {
view->SwapBuffers();
}
int ContextGL_Haiku::get_window_width() {
return window->Bounds().IntegerWidth();
}
int ContextGL_Haiku::get_window_height() {
return window->Bounds().IntegerHeight();
}
#endif

View File

@ -0,0 +1,29 @@
#ifndef CONTEXT_GL_HAIKU_H
#define CONTEXT_GL_HAIKU_H
#if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED)
#include "drivers/gl_context/context_gl.h"
#include "haiku_direct_window.h"
#include "haiku_gl_view.h"
class ContextGL_Haiku : public ContextGL {
private:
HaikuGLView* view;
HaikuDirectWindow* window;
public:
ContextGL_Haiku(HaikuDirectWindow* p_window);
~ContextGL_Haiku();
virtual Error initialize();
virtual void release_current();
virtual void make_current();
virtual void swap_buffers();
virtual int get_window_width();
virtual int get_window_height();
};
#endif
#endif

61
platform/haiku/detect.py Normal file
View File

@ -0,0 +1,61 @@
import os
import sys
def is_active():
return True
def get_name():
return "Haiku"
def can_build():
if (os.name != "posix"):
return False
if (sys.platform == "darwin"):
return False
return True
def get_opts():
return [
('debug_release', 'Add debug symbols to release version','no')
]
def get_flags():
return [
('builtin_zlib', 'no')
]
def configure(env):
is64 = sys.maxsize > 2**32
if (env["bits"]=="default"):
if (is64):
env["bits"]="64"
else:
env["bits"]="32"
env.Append(CPPPATH = ['#platform/haiku'])
env["CC"] = "gcc"
env["CXX"] = "g++"
if (env["target"]=="release"):
if (env["debug_release"]=="yes"):
env.Append(CCFLAGS=['-g2'])
else:
env.Append(CCFLAGS=['-O3','-ffast-math'])
elif (env["target"]=="release_debug"):
env.Append(CCFLAGS=['-O2','-ffast-math','-DDEBUG_ENABLED'])
elif (env["target"]=="debug"):
env.Append(CCFLAGS=['-g2', '-Wall','-DDEBUG_ENABLED','-DDEBUG_MEMORY_ENABLED'])
#env.Append(CCFLAGS=['-DFREETYPE_ENABLED'])
env.Append(CPPFLAGS = ['-DGLEW_ENABLED', '-DOPENGL_ENABLED', '-DMEDIA_KIT_ENABLED'])
env.Append(CPPFLAGS = ['-DUNIX_ENABLED', '-DGLES2_ENABLED', '-DGLES_OVER_GL'])
env.Append(LIBS = ['be', 'game', 'media', 'network', 'bnetapi', 'z', 'GL', 'GLEW'])
import methods
env.Append(BUILDERS = {'GLSL120' : env.Builder(action = methods.build_legacygl_headers, suffix = 'glsl.h',src_suffix = '.glsl')})
env.Append(BUILDERS = {'GLSL' : env.Builder(action = methods.build_glsl_headers, suffix = 'glsl.h',src_suffix = '.glsl')})
env.Append(BUILDERS = {'GLSL120GLES' : env.Builder(action = methods.build_gles2_headers, suffix = 'glsl.h',src_suffix = '.glsl')})

View File

@ -0,0 +1,19 @@
#include "main/main.h"
#include "os_haiku.h"
int main(int argc, char* argv[]) {
OS_Haiku os;
Error error = Main::setup(argv[0], argc-1, &argv[1]);
if (error != OK) {
return 255;
}
if (Main::start()) {
os.run();
}
Main::cleanup();
return os.get_exit_code();
}

View File

@ -0,0 +1,7 @@
#include "haiku_application.h"
HaikuApplication::HaikuApplication()
: BApplication("application/x-vnd.Godot")
{
}

View File

@ -0,0 +1,13 @@
#ifndef HAIKU_APPLICATION_H
#define HAIKU_APPLICATION_H
#include <kernel/image.h> // needed for image_id
#include <Application.h>
class HaikuApplication : public BApplication
{
public:
HaikuApplication();
};
#endif

View File

@ -0,0 +1,344 @@
#include <UnicodeChar.h>
#include "main/main.h"
#include "os/keyboard.h"
#include "haiku_direct_window.h"
#include "key_mapping_haiku.h"
HaikuDirectWindow::HaikuDirectWindow(BRect p_frame)
: BDirectWindow(p_frame, "Godot", B_TITLED_WINDOW, B_QUIT_ON_WINDOW_CLOSE)
{
last_mouse_pos_valid = false;
last_buttons_state = 0;
last_button_mask = 0;
last_key_modifier_state = 0;
}
HaikuDirectWindow::~HaikuDirectWindow() {
if (update_runner) {
delete update_runner;
}
}
void HaikuDirectWindow::SetHaikuGLView(HaikuGLView* p_view) {
view = p_view;
}
void HaikuDirectWindow::StartMessageRunner() {
update_runner = new BMessageRunner(BMessenger(this),
new BMessage(REDRAW_MSG), 1000000/30 /* 30 fps */);
}
void HaikuDirectWindow::StopMessageRunner() {
delete update_runner;
}
void HaikuDirectWindow::SetInput(InputDefault* p_input) {
input = p_input;
}
void HaikuDirectWindow::SetMainLoop(MainLoop* p_main_loop) {
main_loop = p_main_loop;
}
bool HaikuDirectWindow::QuitRequested() {
main_loop->notification(MainLoop::NOTIFICATION_WM_QUIT_REQUEST);
return false;
}
void HaikuDirectWindow::DirectConnected(direct_buffer_info* info) {
view->DirectConnected(info);
view->EnableDirectMode(true);
}
void HaikuDirectWindow::MessageReceived(BMessage* message) {
switch (message->what) {
case REDRAW_MSG:
if (Main::iteration() == true) {
view->EnableDirectMode(false);
Quit();
}
break;
default:
BDirectWindow::MessageReceived(message);
}
}
void HaikuDirectWindow::DispatchMessage(BMessage* message, BHandler* handler) {
switch (message->what) {
case B_MOUSE_DOWN:
case B_MOUSE_UP:
HandleMouseButton(message);
break;
case B_MOUSE_MOVED:
HandleMouseMoved(message);
break;
case B_MOUSE_WHEEL_CHANGED:
HandleMouseWheelChanged(message);
break;
case B_KEY_DOWN:
case B_KEY_UP:
HandleKeyboardEvent(message);
break;
case B_MODIFIERS_CHANGED:
HandleKeyboardModifierEvent(message);
break;
case B_WINDOW_RESIZED:
HandleWindowResized(message);
break;
case LOCKGL_MSG:
view->LockGL();
break;
case UNLOCKGL_MSG:
view->UnlockGL();
break;
default:
BDirectWindow::DispatchMessage(message, handler);
}
}
void HaikuDirectWindow::HandleMouseButton(BMessage* message) {
BPoint where;
if (message->FindPoint("where", &where) != B_OK) {
return;
}
uint32 modifiers = message->FindInt32("modifiers");
uint32 buttons = message->FindInt32("buttons");
uint32 button = buttons ^ last_buttons_state;
last_buttons_state = buttons;
// TODO: implement the mouse_mode checks
//if (mouse_mode == MOUSE_MODE_CAPTURED) {
// event.xbutton.x=last_mouse_pos.x;
// event.xbutton.y=last_mouse_pos.y;
//}
InputEvent mouse_event;
mouse_event.ID = ++event_id;
mouse_event.type = InputEvent::MOUSE_BUTTON;
mouse_event.device = 0;
mouse_event.mouse_button.mod = GetKeyModifierState(modifiers);
mouse_event.mouse_button.button_mask = GetMouseButtonState(buttons);
mouse_event.mouse_button.x = where.x;
mouse_event.mouse_button.y = where.y;
mouse_event.mouse_button.global_x = where.x;
mouse_event.mouse_button.global_y = where.y;
switch (button) {
default:
case B_PRIMARY_MOUSE_BUTTON:
mouse_event.mouse_button.button_index = 1;
break;
case B_SECONDARY_MOUSE_BUTTON:
mouse_event.mouse_button.button_index = 2;
break;
case B_TERTIARY_MOUSE_BUTTON:
mouse_event.mouse_button.button_index = 3;
break;
}
mouse_event.mouse_button.pressed = (message->what == B_MOUSE_DOWN);
if (message->what == B_MOUSE_DOWN && mouse_event.mouse_button.button_index == 1) {
int32 clicks = message->FindInt32("clicks");
if (clicks > 1) {
mouse_event.mouse_button.doubleclick=true;
}
}
input->parse_input_event(mouse_event);
}
void HaikuDirectWindow::HandleMouseMoved(BMessage* message) {
BPoint where;
if (message->FindPoint("where", &where) != B_OK) {
return;
}
Point2i pos(where.x, where.y);
uint32 modifiers = message->FindInt32("modifiers");
uint32 buttons = message->FindInt32("buttons");
if (!last_mouse_pos_valid) {
last_mouse_position = pos;
last_mouse_pos_valid = true;
}
Point2i rel = pos - last_mouse_position;
InputEvent motion_event;
motion_event.ID = ++event_id;
motion_event.type = InputEvent::MOUSE_MOTION;
motion_event.device = 0;
motion_event.mouse_motion.mod = GetKeyModifierState(modifiers);
motion_event.mouse_motion.button_mask = GetMouseButtonState(buttons);
motion_event.mouse_motion.x = pos.x;
motion_event.mouse_motion.y = pos.y;
input->set_mouse_pos(pos);
motion_event.mouse_motion.global_x = pos.x;
motion_event.mouse_motion.global_y = pos.y;
motion_event.mouse_motion.speed_x = input->get_mouse_speed().x;
motion_event.mouse_motion.speed_y = input->get_mouse_speed().y;
motion_event.mouse_motion.relative_x = rel.x;
motion_event.mouse_motion.relative_y = rel.y;
last_mouse_position = pos;
input->parse_input_event(motion_event);
}
void HaikuDirectWindow::HandleMouseWheelChanged(BMessage* message) {
float wheel_delta_y = 0;
if (message->FindFloat("be:wheel_delta_y", &wheel_delta_y) != B_OK) {
return;
}
InputEvent mouse_event;
mouse_event.ID = ++event_id;
mouse_event.type = InputEvent::MOUSE_BUTTON;
mouse_event.device = 0;
mouse_event.mouse_button.button_index = wheel_delta_y < 0 ? 4 : 5;
mouse_event.mouse_button.mod = GetKeyModifierState(last_key_modifier_state);
mouse_event.mouse_button.button_mask = last_button_mask;
mouse_event.mouse_button.x = last_mouse_position.x;
mouse_event.mouse_button.y = last_mouse_position.y;
mouse_event.mouse_button.global_x = last_mouse_position.x;
mouse_event.mouse_button.global_y = last_mouse_position.y;
mouse_event.mouse_button.pressed = true;
input->parse_input_event(mouse_event);
mouse_event.ID = ++event_id;
mouse_event.mouse_button.pressed = false;
input->parse_input_event(mouse_event);
}
void HaikuDirectWindow::HandleKeyboardEvent(BMessage* message) {
int32 raw_char = 0;
int32 key = 0;
int32 modifiers = 0;
if (message->FindInt32("raw_char", &raw_char) != B_OK) {
return;
}
if (message->FindInt32("key", &key) != B_OK) {
return;
}
if (message->FindInt32("modifiers", &modifiers) != B_OK) {
return;
}
InputEvent event;
event.ID = ++event_id;
event.type = InputEvent::KEY;
event.device = 0;
event.key.mod = GetKeyModifierState(modifiers);
event.key.pressed = (message->what == B_KEY_DOWN);
event.key.scancode = KeyMappingHaiku::get_keysym(raw_char, key);
event.key.echo = message->HasInt32("be:key_repeat");
event.key.unicode = 0;
const char* bytes = NULL;
if (message->FindString("bytes", &bytes) == B_OK) {
event.key.unicode = BUnicodeChar::FromUTF8(&bytes);
}
//make it consistent accross platforms.
if (event.key.scancode==KEY_BACKTAB) {
event.key.scancode=KEY_TAB;
event.key.mod.shift=true;
}
input->parse_input_event(event);
}
void HaikuDirectWindow::HandleKeyboardModifierEvent(BMessage* message) {
int32 old_modifiers = 0;
int32 modifiers = 0;
if (message->FindInt32("be:old_modifiers", &old_modifiers) != B_OK) {
return;
}
if (message->FindInt32("modifiers", &modifiers) != B_OK) {
return;
}
int32 key = old_modifiers ^ modifiers;
InputEvent event;
event.ID = ++event_id;
event.type = InputEvent::KEY;
event.device = 0;
event.key.mod = GetKeyModifierState(modifiers);
event.key.pressed = ((modifiers & key) != 0);
event.key.scancode = KeyMappingHaiku::get_modifier_keysym(key);
event.key.echo = false;
event.key.unicode = 0;
input->parse_input_event(event);
}
void HaikuDirectWindow::HandleWindowResized(BMessage* message) {
int32 width = 0;
int32 height = 0;
if ((message->FindInt32("width", &width) != B_OK) || (message->FindInt32("height", &height) != B_OK)) {
return;
}
current_video_mode->width = width;
current_video_mode->height = height;
}
inline InputModifierState HaikuDirectWindow::GetKeyModifierState(uint32 p_state) {
last_key_modifier_state = p_state;
InputModifierState state;
state.shift = (p_state & B_SHIFT_KEY) != 0;
state.control = (p_state & B_CONTROL_KEY) != 0;
state.alt = (p_state & B_OPTION_KEY) != 0;
state.meta = (p_state & B_COMMAND_KEY) != 0;
return state;
}
inline int HaikuDirectWindow::GetMouseButtonState(uint32 p_state) {
int state = 0;
if (p_state & B_PRIMARY_MOUSE_BUTTON) {
state |= 1 << 0;
}
if (p_state & B_SECONDARY_MOUSE_BUTTON) {
state |= 1 << 1;
}
if (p_state & B_TERTIARY_MOUSE_BUTTON) {
state |= 1 << 2;
}
last_button_mask = state;
return state;
}

View File

@ -0,0 +1,60 @@
#ifndef HAIKU_DIRECT_WINDOW_H
#define HAIKU_DIRECT_WINDOW_H
#include <kernel/image.h> // needed for image_id
#include <DirectWindow.h>
#include "core/os/os.h"
#include "main/input_default.h"
#include "haiku_gl_view.h"
#define REDRAW_MSG 'rdrw'
#define LOCKGL_MSG 'glck'
#define UNLOCKGL_MSG 'ulck'
class HaikuDirectWindow : public BDirectWindow
{
private:
unsigned int event_id;
Point2i last_mouse_position;
bool last_mouse_pos_valid;
uint32 last_buttons_state;
uint32 last_key_modifier_state;
int last_button_mask;
OS::VideoMode* current_video_mode;
MainLoop* main_loop;
InputDefault* input;
HaikuGLView* view;
BMessageRunner* update_runner;
void HandleMouseButton(BMessage* message);
void HandleMouseMoved(BMessage* message);
void HandleMouseWheelChanged(BMessage* message);
void HandleWindowResized(BMessage* message);
void HandleKeyboardEvent(BMessage* message);
void HandleKeyboardModifierEvent(BMessage* message);
inline InputModifierState GetKeyModifierState(uint32 p_state);
inline int GetMouseButtonState(uint32 p_state);
public:
HaikuDirectWindow(BRect p_frame);
~HaikuDirectWindow();
void SetHaikuGLView(HaikuGLView* p_view);
void StartMessageRunner();
void StopMessageRunner();
void SetInput(InputDefault* p_input);
void SetMainLoop(MainLoop* p_main_loop);
inline void SetVideoMode(OS::VideoMode* video_mode) { current_video_mode = video_mode; };
virtual bool QuitRequested();
virtual void DirectConnected(direct_buffer_info* info);
virtual void MessageReceived(BMessage* message);
virtual void DispatchMessage(BMessage* message, BHandler* handler);
inline Point2i GetLastMousePosition() { return last_mouse_position; };
inline int GetLastButtonMask() { return last_button_mask; };
};
#endif

View File

@ -0,0 +1,18 @@
#include "main/main.h"
#include "haiku_gl_view.h"
HaikuGLView::HaikuGLView(BRect frame, uint32 type)
: BGLView(frame, "GodotGLView", B_FOLLOW_ALL_SIDES, 0, type)
{
}
void HaikuGLView::AttachedToWindow(void) {
LockGL();
BGLView::AttachedToWindow();
UnlockGL();
MakeFocus();
}
void HaikuGLView::Draw(BRect updateRect) {
Main::force_redraw();
}

View File

@ -0,0 +1,15 @@
#ifndef HAIKU_GL_VIEW_H
#define HAIKU_GL_VIEW_H
#include <kernel/image.h> // needed for image_id
#include <GLView.h>
class HaikuGLView : public BGLView
{
public:
HaikuGLView(BRect frame, uint32 type);
virtual void AttachedToWindow(void);
virtual void Draw(BRect updateRect);
};
#endif

View File

@ -0,0 +1,193 @@
#include <InterfaceDefs.h>
#include "key_mapping_haiku.h"
#include "os/keyboard.h"
struct _HaikuTranslatePair {
unsigned int keysym;
int32 keycode;
};
static _HaikuTranslatePair _mod_to_keycode[] = {
{ KEY_SHIFT, B_SHIFT_KEY },
{ KEY_ALT, B_COMMAND_KEY },
{ KEY_CONTROL, B_CONTROL_KEY },
{ KEY_CAPSLOCK, B_CAPS_LOCK },
{ KEY_SCROLLLOCK, B_SCROLL_LOCK },
{ KEY_NUMLOCK, B_NUM_LOCK },
{ KEY_SUPER_L, B_OPTION_KEY },
{ KEY_MENU, B_MENU_KEY },
{ KEY_SHIFT, B_LEFT_SHIFT_KEY },
{ KEY_SHIFT, B_RIGHT_SHIFT_KEY },
{ KEY_ALT, B_LEFT_COMMAND_KEY },
{ KEY_ALT, B_RIGHT_COMMAND_KEY },
{ KEY_CONTROL, B_LEFT_CONTROL_KEY },
{ KEY_CONTROL, B_RIGHT_CONTROL_KEY },
{ KEY_SUPER_L, B_LEFT_OPTION_KEY },
{ KEY_SUPER_R, B_RIGHT_OPTION_KEY },
{ KEY_UNKNOWN, 0 }
};
static _HaikuTranslatePair _fn_to_keycode[] = {
{ KEY_F1, B_F1_KEY },
{ KEY_F2, B_F2_KEY },
{ KEY_F3, B_F3_KEY },
{ KEY_F4, B_F4_KEY },
{ KEY_F5, B_F5_KEY },
{ KEY_F6, B_F6_KEY },
{ KEY_F7, B_F7_KEY },
{ KEY_F8, B_F8_KEY },
{ KEY_F9, B_F9_KEY },
{ KEY_F10, B_F10_KEY },
{ KEY_F11, B_F11_KEY },
{ KEY_F12, B_F12_KEY },
//{ KEY_F13, ? },
//{ KEY_F14, ? },
//{ KEY_F15, ? },
//{ KEY_F16, ? },
{ KEY_PRINT, B_PRINT_KEY },
{ KEY_SCROLLLOCK, B_SCROLL_KEY },
{ KEY_PAUSE, B_PAUSE_KEY },
{ KEY_UNKNOWN, 0 }
};
static _HaikuTranslatePair _hb_to_keycode[] = {
{ KEY_BACKSPACE, B_BACKSPACE },
{ KEY_TAB, B_TAB },
{ KEY_RETURN, B_RETURN },
{ KEY_CAPSLOCK, B_CAPS_LOCK },
{ KEY_ESCAPE, B_ESCAPE },
{ KEY_SPACE, B_SPACE },
{ KEY_PAGEUP, B_PAGE_UP },
{ KEY_PAGEDOWN, B_PAGE_DOWN },
{ KEY_END, B_END },
{ KEY_HOME, B_HOME },
{ KEY_LEFT, B_LEFT_ARROW },
{ KEY_UP, B_UP_ARROW },
{ KEY_RIGHT, B_RIGHT_ARROW },
{ KEY_DOWN, B_DOWN_ARROW },
{ KEY_PRINT, B_PRINT_KEY },
{ KEY_INSERT, B_INSERT },
{ KEY_DELETE, B_DELETE },
// { KEY_HELP, ??? },
{ KEY_0, (0x30) },
{ KEY_1, (0x31) },
{ KEY_2, (0x32) },
{ KEY_3, (0x33) },
{ KEY_4, (0x34) },
{ KEY_5, (0x35) },
{ KEY_6, (0x36) },
{ KEY_7, (0x37) },
{ KEY_8, (0x38) },
{ KEY_9, (0x39) },
{ KEY_A, (0x61) },
{ KEY_B, (0x62) },
{ KEY_C, (0x63) },
{ KEY_D, (0x64) },
{ KEY_E, (0x65) },
{ KEY_F, (0x66) },
{ KEY_G, (0x67) },
{ KEY_H, (0x68) },
{ KEY_I, (0x69) },
{ KEY_J, (0x6A) },
{ KEY_K, (0x6B) },
{ KEY_L, (0x6C) },
{ KEY_M, (0x6D) },
{ KEY_N, (0x6E) },
{ KEY_O, (0x6F) },
{ KEY_P, (0x70) },
{ KEY_Q, (0x71) },
{ KEY_R, (0x72) },
{ KEY_S, (0x73) },
{ KEY_T, (0x74) },
{ KEY_U, (0x75) },
{ KEY_V, (0x76) },
{ KEY_W, (0x77) },
{ KEY_X, (0x78) },
{ KEY_Y, (0x79) },
{ KEY_Z, (0x7A) },
/*
{ KEY_PLAY, VK_PLAY},// (0xFA)
{ KEY_STANDBY,VK_SLEEP },//(0x5F)
{ KEY_BACK,VK_BROWSER_BACK},// (0xA6)
{ KEY_FORWARD,VK_BROWSER_FORWARD},// (0xA7)
{ KEY_REFRESH,VK_BROWSER_REFRESH},// (0xA8)
{ KEY_STOP,VK_BROWSER_STOP},// (0xA9)
{ KEY_SEARCH,VK_BROWSER_SEARCH},// (0xAA)
{ KEY_FAVORITES, VK_BROWSER_FAVORITES},// (0xAB)
{ KEY_HOMEPAGE,VK_BROWSER_HOME},// (0xAC)
{ KEY_VOLUMEMUTE,VK_VOLUME_MUTE},// (0xAD)
{ KEY_VOLUMEDOWN,VK_VOLUME_DOWN},// (0xAE)
{ KEY_VOLUMEUP,VK_VOLUME_UP},// (0xAF)
{ KEY_MEDIANEXT,VK_MEDIA_NEXT_TRACK},// (0xB0)
{ KEY_MEDIAPREVIOUS,VK_MEDIA_PREV_TRACK},// (0xB1)
{ KEY_MEDIASTOP,VK_MEDIA_STOP},// (0xB2)
{ KEY_LAUNCHMAIL, VK_LAUNCH_MAIL},// (0xB4)
{ KEY_LAUNCHMEDIA,VK_LAUNCH_MEDIA_SELECT},// (0xB5)
{ KEY_LAUNCH0,VK_LAUNCH_APP1},// (0xB6)
{ KEY_LAUNCH1,VK_LAUNCH_APP2},// (0xB7)
*/
{ KEY_SEMICOLON, 0x3B },
{ KEY_EQUAL, 0x3D },
{ KEY_COLON, 0x2C },
{ KEY_MINUS, 0x2D },
{ KEY_PERIOD, 0x2E },
{ KEY_SLASH, 0x2F },
{ KEY_KP_MULTIPLY, 0x2A },
{ KEY_KP_ADD, 0x2B },
{ KEY_QUOTELEFT, 0x60 },
{ KEY_BRACKETLEFT, 0x5B },
{ KEY_BACKSLASH, 0x5C },
{ KEY_BRACKETRIGHT, 0x5D },
{ KEY_APOSTROPHE, 0x27 },
{ KEY_UNKNOWN, 0 }
};
unsigned int KeyMappingHaiku::get_keysym(int32 raw_char, int32 key) {
if (raw_char == B_INSERT && key == 0x64) { return KEY_KP_0; }
if (raw_char == B_END && key == 0x58) { return KEY_KP_1; }
if (raw_char == B_DOWN_ARROW && key == 0x59) { return KEY_KP_2; }
if (raw_char == B_PAGE_DOWN && key == 0x5A) { return KEY_KP_3; }
if (raw_char == B_LEFT_ARROW && key == 0x48) { return KEY_KP_4; }
if (raw_char == 0x35 && key == 0x49) { return KEY_KP_5; }
if (raw_char == B_RIGHT_ARROW && key == 0x4A) { return KEY_KP_6; }
if (raw_char == B_HOME && key == 0x37) { return KEY_KP_7; }
if (raw_char == B_UP_ARROW && key == 0x38) { return KEY_KP_8; }
if (raw_char == B_PAGE_UP && key == 0x39) { return KEY_KP_9; }
if (raw_char == 0x2F && key == 0x23) { return KEY_KP_DIVIDE; }
if (raw_char == 0x2D && key == 0x25) { return KEY_KP_SUBSTRACT; }
if (raw_char == B_DELETE && key == 0x65) { return KEY_KP_PERIOD; }
if (raw_char == 0x10) {
for(int i = 0; _fn_to_keycode[i].keysym != KEY_UNKNOWN; i++) {
if (_fn_to_keycode[i].keycode == key) {
return _fn_to_keycode[i].keysym;
}
}
return KEY_UNKNOWN;
}
for(int i = 0; _hb_to_keycode[i].keysym != KEY_UNKNOWN; i++) {
if (_hb_to_keycode[i].keycode == raw_char) {
return _hb_to_keycode[i].keysym;
}
}
return KEY_UNKNOWN;
}
unsigned int KeyMappingHaiku::get_modifier_keysym(int32 key) {
for(int i = 0; _mod_to_keycode[i].keysym != KEY_UNKNOWN; i++) {
if ((_mod_to_keycode[i].keycode & key) != 0) {
return _mod_to_keycode[i].keysym;
}
}
return KEY_UNKNOWN;
}

View File

@ -0,0 +1,13 @@
#ifndef KEY_MAPPING_HAIKU_H
#define KEY_MAPPING_HAIKU_H
class KeyMappingHaiku
{
KeyMappingHaiku() {};
public:
static unsigned int get_keysym(int32 raw_char, int32 key);
static unsigned int get_modifier_keysym(int32 key);
};
#endif

BIN
platform/haiku/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

320
platform/haiku/os_haiku.cpp Normal file
View File

@ -0,0 +1,320 @@
#include <Screen.h>
#include "servers/visual/visual_server_raster.h"
#include "servers/visual/visual_server_wrap_mt.h"
#include "drivers/gles2/rasterizer_gles2.h"
#include "servers/physics/physics_server_sw.h"
//#include "servers/physics_2d/physics_2d_server_wrap_mt.h"
#include "main/main.h"
#include "os_haiku.h"
OS_Haiku::OS_Haiku() {
#ifdef MEDIA_KIT_ENABLED
AudioDriverManagerSW::add_driver(&driver_media_kit);
#endif
};
void OS_Haiku::run() {
if (!main_loop) {
return;
}
main_loop->init();
context_gl->release_current();
// TODO: clean up
BMessenger* bms = new BMessenger(window);
BMessage* msg = new BMessage();
bms->SendMessage(LOCKGL_MSG, msg);
window->StartMessageRunner();
app->Run();
window->StopMessageRunner();
delete app;
delete bms;
delete msg;
main_loop->finish();
}
String OS_Haiku::get_name() {
return "Haiku";
}
int OS_Haiku::get_video_driver_count() const {
return 1;
}
const char* OS_Haiku::get_video_driver_name(int p_driver) const {
return "GLES2";
}
OS::VideoMode OS_Haiku::get_default_video_mode() const {
return OS::VideoMode(800, 600, false);
}
void OS_Haiku::initialize(const VideoMode& p_desired, int p_video_driver, int p_audio_driver) {
main_loop = NULL;
current_video_mode = p_desired;
app = new HaikuApplication();
BRect frame;
frame.Set(50, 50, 50 + current_video_mode.width - 1, 50 + current_video_mode.height - 1);
window = new HaikuDirectWindow(frame);
window->SetVideoMode(&current_video_mode);
if (current_video_mode.fullscreen) {
window->SetFullScreen(true);
}
if (!current_video_mode.resizable) {
uint32 flags = window->Flags();
flags |= B_NOT_RESIZABLE;
window->SetFlags(flags);
}
#if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED)
context_gl = memnew(ContextGL_Haiku(window));
context_gl->initialize();
context_gl->make_current();
rasterizer = memnew(RasterizerGLES2);
#endif
visual_server = memnew(VisualServerRaster(rasterizer));
ERR_FAIL_COND(!visual_server);
// TODO: enable multithreaded VS
//if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) {
// visual_server = memnew(VisualServerWrapMT(visual_server, get_render_thread_mode() == RENDER_SEPARATE_THREAD));
//}
input = memnew(InputDefault);
window->SetInput(input);
window->Show();
visual_server->init();
physics_server = memnew(PhysicsServerSW);
physics_server->init();
physics_2d_server = memnew(Physics2DServerSW);
// TODO: enable multithreaded PS
//physics_2d_server = Physics2DServerWrapMT::init_server<Physics2DServerSW>();
physics_2d_server->init();
AudioDriverManagerSW::get_driver(p_audio_driver)->set_singleton();
if (AudioDriverManagerSW::get_driver(p_audio_driver)->init() != OK) {
ERR_PRINT("Initializing audio failed.");
}
sample_manager = memnew(SampleManagerMallocSW);
audio_server = memnew(AudioServerSW(sample_manager));
audio_server->init();
spatial_sound_server = memnew(SpatialSoundServerSW);
spatial_sound_server->init();
spatial_sound_2d_server = memnew(SpatialSound2DServerSW);
spatial_sound_2d_server->init();
}
void OS_Haiku::finalize() {
if (main_loop) {
memdelete(main_loop);
}
main_loop = NULL;
spatial_sound_server->finish();
memdelete(spatial_sound_server);
spatial_sound_2d_server->finish();
memdelete(spatial_sound_2d_server);
audio_server->finish();
memdelete(audio_server);
memdelete(sample_manager);
visual_server->finish();
memdelete(visual_server);
memdelete(rasterizer);
physics_server->finish();
memdelete(physics_server);
physics_2d_server->finish();
memdelete(physics_2d_server);
memdelete(input);
#if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED)
memdelete(context_gl);
#endif
}
void OS_Haiku::set_main_loop(MainLoop* p_main_loop) {
main_loop = p_main_loop;
input->set_main_loop(p_main_loop);
window->SetMainLoop(p_main_loop);
}
MainLoop* OS_Haiku::get_main_loop() const {
return main_loop;
}
void OS_Haiku::delete_main_loop() {
if (main_loop) {
memdelete(main_loop);
}
main_loop = NULL;
window->SetMainLoop(NULL);
}
void OS_Haiku::release_rendering_thread() {
context_gl->release_current();
}
void OS_Haiku::make_rendering_thread() {
context_gl->make_current();
}
bool OS_Haiku::can_draw() const {
// TODO: implement
return true;
}
void OS_Haiku::swap_buffers() {
context_gl->swap_buffers();
}
Point2 OS_Haiku::get_mouse_pos() const {
return window->GetLastMousePosition();
}
int OS_Haiku::get_mouse_button_state() const {
return window->GetLastButtonMask();
}
void OS_Haiku::set_cursor_shape(CursorShape p_shape) {
//ERR_PRINT("set_cursor_shape() NOT IMPLEMENTED");
}
int OS_Haiku::get_screen_count() const {
// TODO: implement get_screen_count()
return 1;
}
int OS_Haiku::get_current_screen() const {
// TODO: implement get_current_screen()
return 0;
}
void OS_Haiku::set_current_screen(int p_screen) {
// TODO: implement set_current_screen()
}
Point2 OS_Haiku::get_screen_position(int p_screen) const {
// TODO: make this work with the p_screen parameter
BScreen* screen = new BScreen(window);
BRect frame = screen->Frame();
delete screen;
return Point2i(frame.left, frame.top);
}
Size2 OS_Haiku::get_screen_size(int p_screen) const {
// TODO: make this work with the p_screen parameter
BScreen* screen = new BScreen(window);
BRect frame = screen->Frame();
delete screen;
return Size2i(frame.IntegerWidth() + 1, frame.IntegerHeight() + 1);
}
void OS_Haiku::set_window_title(const String& p_title) {
window->SetTitle(p_title.utf8().get_data());
}
Size2 OS_Haiku::get_window_size() const {
BSize size = window->Size();
return Size2i(size.IntegerWidth() + 1, size.IntegerHeight() + 1);
}
void OS_Haiku::set_window_size(const Size2 p_size) {
// TODO: why does it stop redrawing after this is called?
window->ResizeTo(p_size.x, p_size.y);
}
Point2 OS_Haiku::get_window_position() const {
BPoint point(0, 0);
window->ConvertToScreen(&point);
return Point2i(point.x, point.y);
}
void OS_Haiku::set_window_position(const Point2& p_position) {
window->MoveTo(p_position.x, p_position.y);
}
void OS_Haiku::set_window_fullscreen(bool p_enabled) {
window->SetFullScreen(p_enabled);
current_video_mode.fullscreen = p_enabled;
visual_server->init();
}
bool OS_Haiku::is_window_fullscreen() const {
return current_video_mode.fullscreen;
}
void OS_Haiku::set_window_resizable(bool p_enabled) {
uint32 flags = window->Flags();
if (p_enabled) {
flags &= ~(B_NOT_RESIZABLE);
} else {
flags |= B_NOT_RESIZABLE;
}
window->SetFlags(flags);
current_video_mode.resizable = p_enabled;
}
bool OS_Haiku::is_window_resizable() const {
return current_video_mode.resizable;
}
void OS_Haiku::set_window_minimized(bool p_enabled) {
window->Minimize(p_enabled);
}
bool OS_Haiku::is_window_minimized() const {
return window->IsMinimized();
}
void OS_Haiku::set_window_maximized(bool p_enabled) {
window->Minimize(!p_enabled);
}
bool OS_Haiku::is_window_maximized() const {
return !window->IsMinimized();
}
void OS_Haiku::set_video_mode(const VideoMode& p_video_mode, int p_screen) {
ERR_PRINT("set_video_mode() NOT IMPLEMENTED");
}
OS::VideoMode OS_Haiku::get_video_mode(int p_screen) const {
return current_video_mode;
}
void OS_Haiku::get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen) const {
ERR_PRINT("get_fullscreen_mode_list() NOT IMPLEMENTED");
}
String OS_Haiku::get_executable_path() const {
return OS::get_executable_path();
}

99
platform/haiku/os_haiku.h Normal file
View File

@ -0,0 +1,99 @@
#ifndef OS_HAIKU_H
#define OS_HAIKU_H
#include "drivers/unix/os_unix.h"
#include "servers/visual_server.h"
#include "servers/visual/rasterizer.h"
#include "servers/physics_server.h"
#include "servers/physics_2d/physics_2d_server_sw.h"
#include "servers/audio/audio_server_sw.h"
#include "servers/audio/sample_manager_sw.h"
#include "servers/spatial_sound/spatial_sound_server_sw.h"
#include "servers/spatial_sound_2d/spatial_sound_2d_server_sw.h"
#include "main/input_default.h"
#include "audio_driver_media_kit.h"
#include "context_gl_haiku.h"
#include "haiku_application.h"
#include "haiku_direct_window.h"
class OS_Haiku : public OS_Unix {
private:
HaikuApplication* app;
HaikuDirectWindow* window;
MainLoop* main_loop;
InputDefault* input;
Rasterizer* rasterizer;
VisualServer* visual_server;
VideoMode current_video_mode;
PhysicsServer* physics_server;
Physics2DServer* physics_2d_server;
AudioServerSW* audio_server;
SampleManagerMallocSW* sample_manager;
SpatialSoundServerSW* spatial_sound_server;
SpatialSound2DServerSW* spatial_sound_2d_server;
#ifdef MEDIA_KIT_ENABLED
AudioDriverMediaKit driver_media_kit;
#endif
#if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED)
ContextGL_Haiku* context_gl;
#endif
virtual void delete_main_loop();
protected:
virtual int get_video_driver_count() const;
virtual const char* get_video_driver_name(int p_driver) const;
virtual VideoMode get_default_video_mode() const;
virtual void initialize(const VideoMode& p_desired, int p_video_driver, int p_audio_driver);
virtual void finalize();
virtual void set_main_loop(MainLoop* p_main_loop);
public:
OS_Haiku();
void run();
virtual String get_name();
virtual MainLoop* get_main_loop() const;
virtual bool can_draw() const;
virtual void release_rendering_thread();
virtual void make_rendering_thread();
virtual void swap_buffers();
virtual Point2 get_mouse_pos() const;
virtual int get_mouse_button_state() const;
virtual void set_cursor_shape(CursorShape p_shape);
virtual int get_screen_count() const;
virtual int get_current_screen() const;
virtual void set_current_screen(int p_screen);
virtual Point2 get_screen_position(int p_screen=0) const;
virtual Size2 get_screen_size(int p_screen=0) const;
virtual void set_window_title(const String& p_title);
virtual Size2 get_window_size() const;
virtual void set_window_size(const Size2 p_size);
virtual Point2 get_window_position() const;
virtual void set_window_position(const Point2& p_position);
virtual void set_window_fullscreen(bool p_enabled);
virtual bool is_window_fullscreen() const;
virtual void set_window_resizable(bool p_enabled);
virtual bool is_window_resizable() const;
virtual void set_window_minimized(bool p_enabled);
virtual bool is_window_minimized() const;
virtual void set_window_maximized(bool p_enabled);
virtual bool is_window_maximized() const;
virtual void set_video_mode(const VideoMode& p_video_mode, int p_screen=0);
virtual VideoMode get_video_mode(int p_screen=0) const;
virtual void get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen=0) const;
virtual String get_executable_path() const;
};
#endif

View File

@ -0,0 +1,6 @@
#include <alloca.h>
// for ifaddrs.h needed in drivers/unix/ip_unix.cpp
#define _BSD_SOURCE 1
#define GLES2_INCLUDE_H <GL/glew.h>

View File

@ -157,6 +157,8 @@ public:
Error shell_open(String p_uri);
void push_input(const InputEvent& p_event);
String get_locale() const;
virtual void set_video_mode(const VideoMode& p_video_mode,int p_screen=0);
virtual VideoMode get_video_mode(int p_screen=0) const;
virtual void get_fullscreen_mode_list(List<VideoMode> *p_list,int p_screen=0) const;

View File

@ -1254,6 +1254,11 @@ Error OS_OSX::shell_open(String p_uri) {
return OK;
}
String OS_OSX::get_locale() const {
NSString* preferredLang = [[NSLocale preferredLanguages] objectAtIndex:0];
return [preferredLang UTF8String];
}
void OS_OSX::swap_buffers() {
[context flushBuffer];

View File

@ -79,6 +79,13 @@ Error TCPServerWinsock::listen(uint16_t p_port,const List<String> *p_accepted_ho
my_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP TODO: use p_accepted_hosts
memset(my_addr.sin_zero, '\0', sizeof my_addr.sin_zero);
int reuse=1;
if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) < 0) {
printf("REUSEADDR failed!");
}
if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof my_addr) != SOCKET_ERROR) {
if (::listen(sockfd, SOMAXCONN) == SOCKET_ERROR) {

View File

@ -784,8 +784,6 @@ void OS_X11::set_window_size(const Size2 p_size) {
void OS_X11::set_window_fullscreen(bool p_enabled) {
set_wm_fullscreen(p_enabled);
current_videomode.fullscreen = p_enabled;
visual_server->init();
}
bool OS_X11::is_window_fullscreen() const {
@ -891,8 +889,14 @@ void OS_X11::set_window_maximized(bool p_enabled) {
xev.xclient.data.l[2] = wm_max_vert;
XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
/* sorry this does not fix it, fails on multi monitor
XWindowAttributes xwa;
XGetWindowAttributes(x11_display,DefaultRootWindow(x11_display),&xwa);
current_videomode.width = xwa.width;
current_videomode.height = xwa.height;
*/
maximized = p_enabled;
}
bool OS_X11::is_window_maximized() const {
@ -1201,7 +1205,6 @@ void OS_X11::process_xevents() {
#ifdef NEW_WM_API
if(current_videomode.fullscreen) {
set_wm_fullscreen(true);
visual_server->init();
}
#endif
main_loop->notification(MainLoop::NOTIFICATION_WM_FOCUS_IN);
@ -1218,7 +1221,6 @@ void OS_X11::process_xevents() {
if(current_videomode.fullscreen) {
set_wm_fullscreen(false);
set_window_minimized(true);
visual_server->init();
}
#endif
main_loop->notification(MainLoop::NOTIFICATION_WM_FOCUS_OUT);

View File

@ -126,7 +126,7 @@ void Joint2D::_bind_methods() {
ADD_PROPERTY( PropertyInfo( Variant::NODE_PATH, "node_a"), _SCS("set_node_a"),_SCS("get_node_a") );
ADD_PROPERTY( PropertyInfo( Variant::NODE_PATH, "node_b"), _SCS("set_node_b"),_SCS("get_node_b") );
ADD_PROPERTY( PropertyInfo( Variant::REAL, "bias/bias",PROPERTY_HINT_RANGE,"0,0.9,0.01"), _SCS("set_bias"),_SCS("get_bias") );
ADD_PROPERTY( PropertyInfo( Variant::REAL, "bias/bias",PROPERTY_HINT_RANGE,"0,0.9,0.001"), _SCS("set_bias"),_SCS("get_bias") );
}
@ -175,15 +175,37 @@ RID PinJoint2D::_configure_joint() {
//add a collision exception between both
Physics2DServer::get_singleton()->body_add_collision_exception(body_a->get_rid(),body_b->get_rid());
}
return Physics2DServer::get_singleton()->pin_joint_create(get_global_transform().get_origin(),body_a->get_rid(),body_b?body_b->get_rid():RID());
RID pj = Physics2DServer::get_singleton()->pin_joint_create(get_global_transform().get_origin(),body_a->get_rid(),body_b?body_b->get_rid():RID());
Physics2DServer::get_singleton()->pin_joint_set_param(pj, Physics2DServer::PIN_JOINT_SOFTNESS, softness);
return pj;
}
void PinJoint2D::set_softness(real_t p_softness) {
softness=p_softness;
update();
if (get_joint().is_valid())
Physics2DServer::get_singleton()->pin_joint_set_param(get_joint(), Physics2DServer::PIN_JOINT_SOFTNESS, p_softness);
}
real_t PinJoint2D::get_softness() const {
return softness;
}
void PinJoint2D::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_softness","softness"), &PinJoint2D::set_softness);
ObjectTypeDB::bind_method(_MD("get_softness"), &PinJoint2D::get_softness);
ADD_PROPERTY( PropertyInfo( Variant::REAL, "softness", PROPERTY_HINT_EXP_RANGE,"0.00,16,0.01"), _SCS("set_softness"), _SCS("get_softness"));
}
PinJoint2D::PinJoint2D() {
softness = 0;
}

View File

@ -72,13 +72,17 @@ class PinJoint2D : public Joint2D {
OBJ_TYPE(PinJoint2D,Joint2D);
real_t softness;
protected:
void _notification(int p_what);
virtual RID _configure_joint();
static void _bind_methods();
public:
void set_softness(real_t p_stiffness);
real_t get_softness() const;
PinJoint2D();
};

View File

@ -110,7 +110,10 @@ void ParallaxBackground::_update_scroll() {
if (!l)
continue;
l->set_base_offset_and_scale(ofs,scale);
if (ignore_camera_zoom)
l->set_base_offset_and_scale(ofs, 1.0);
else
l->set_base_offset_and_scale(ofs, scale);
}
}
@ -165,6 +168,18 @@ Point2 ParallaxBackground::get_limit_end() const {
return limit_end;
}
void ParallaxBackground::set_ignore_camera_zoom(bool ignore){
ignore_camera_zoom = ignore;
}
bool ParallaxBackground::is_ignore_camera_zoom(){
return ignore_camera_zoom;
}
void ParallaxBackground::_bind_methods() {
ObjectTypeDB::bind_method(_MD("_camera_moved"),&ParallaxBackground::_camera_moved);
@ -178,6 +193,8 @@ void ParallaxBackground::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_limit_begin"),&ParallaxBackground::get_limit_begin);
ObjectTypeDB::bind_method(_MD("set_limit_end","ofs"),&ParallaxBackground::set_limit_end);
ObjectTypeDB::bind_method(_MD("get_limit_end"),&ParallaxBackground::get_limit_end);
ObjectTypeDB::bind_method(_MD("set_ignore_camera_zoom"), &ParallaxBackground::set_ignore_camera_zoom);
ObjectTypeDB::bind_method(_MD("is_ignore_camera_zoom"), &ParallaxBackground::is_ignore_camera_zoom);
ADD_PROPERTY( PropertyInfo(Variant::VECTOR2,"scroll/offset"),_SCS("set_scroll_offset"),_SCS("get_scroll_offset"));
@ -185,6 +202,7 @@ void ParallaxBackground::_bind_methods() {
ADD_PROPERTY( PropertyInfo(Variant::VECTOR2,"scroll/base_scale"),_SCS("set_scroll_base_scale"),_SCS("get_scroll_base_scale"));
ADD_PROPERTY( PropertyInfo(Variant::VECTOR2,"scroll/limit_begin"),_SCS("set_limit_begin"),_SCS("get_limit_begin"));
ADD_PROPERTY( PropertyInfo(Variant::VECTOR2,"scroll/limit_end"),_SCS("set_limit_end"),_SCS("get_limit_end"));
ADD_PROPERTY( PropertyInfo(Variant::BOOL, "scroll/ignore_camera_zoom"), _SCS("set_ignore_camera_zoom"), _SCS("is_ignore_camera_zoom"));
}

View File

@ -44,6 +44,7 @@ class ParallaxBackground : public CanvasLayer {
String group_name;
Point2 limit_begin;
Point2 limit_end;
bool ignore_camera_zoom;
void _update_scroll();
protected:
@ -72,6 +73,9 @@ public:
void set_limit_end(const Point2& p_ofs);
Point2 get_limit_end() const;
void set_ignore_camera_zoom(bool ignore);
bool is_ignore_camera_zoom();
ParallaxBackground();
};

View File

@ -53,6 +53,16 @@ uint32_t RayCast2D::get_layer_mask() const {
return layer_mask;
}
void RayCast2D::set_type_mask(uint32_t p_mask) {
type_mask=p_mask;
}
uint32_t RayCast2D::get_type_mask() const {
return type_mask;
}
bool RayCast2D::is_colliding() const{
return collided;
@ -162,7 +172,7 @@ void RayCast2D::_notification(int p_what) {
Physics2DDirectSpaceState::RayResult rr;
if (dss->intersect_ray(gt.get_origin(),gt.xform(to),rr,exclude,layer_mask)) {
if (dss->intersect_ray(gt.get_origin(),gt.xform(to),rr,exclude,layer_mask,type_mask)) {
collided=true;
against=rr.collider_id;
@ -241,9 +251,13 @@ void RayCast2D::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_layer_mask","mask"),&RayCast2D::set_layer_mask);
ObjectTypeDB::bind_method(_MD("get_layer_mask"),&RayCast2D::get_layer_mask);
ObjectTypeDB::bind_method(_MD("set_type_mask","mask"),&RayCast2D::set_type_mask);
ObjectTypeDB::bind_method(_MD("get_type_mask"),&RayCast2D::get_type_mask);
ADD_PROPERTY(PropertyInfo(Variant::BOOL,"enabled"),_SCS("set_enabled"),_SCS("is_enabled"));
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2,"cast_to"),_SCS("set_cast_to"),_SCS("get_cast_to"));
ADD_PROPERTY(PropertyInfo(Variant::INT,"layer_mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_layer_mask"),_SCS("get_layer_mask"));
ADD_PROPERTY(PropertyInfo(Variant::INT,"type_mask",PROPERTY_HINT_FLAGS,"Static,Kinematic,Rigid,Character,Area"),_SCS("set_type_mask"),_SCS("get_type_mask"));
}
RayCast2D::RayCast2D() {
@ -253,5 +267,6 @@ RayCast2D::RayCast2D() {
collided=false;
against_shape=0;
layer_mask=1;
type_mask=Physics2DDirectSpaceState::TYPE_MASK_COLLISION;
cast_to=Vector2(0,50);
}

View File

@ -44,6 +44,7 @@ class RayCast2D : public Node2D {
Vector2 collision_normal;
Set<RID> exclude;
uint32_t layer_mask;
uint32_t type_mask;
Vector2 cast_to;
@ -62,6 +63,9 @@ public:
void set_layer_mask(uint32_t p_mask);
uint32_t get_layer_mask() const;
void set_type_mask(uint32_t p_mask);
uint32_t get_type_mask() const;
bool is_colliding() const;
Object *get_collider() const;
int get_collider_shape() const;

View File

@ -81,7 +81,7 @@ float BakedLightSampler::get_param(Param p_param) const{
void BakedLightSampler::set_resolution(int p_resolution){
ERR_FAIL_COND(p_resolution<4 && p_resolution>32);
ERR_FAIL_COND(p_resolution<4 || p_resolution>32);
resolution=p_resolution;
VS::get_singleton()->baked_light_sampler_set_resolution(base,resolution);
}

View File

@ -126,7 +126,7 @@ void CollisionPolygon::_notification(int p_what) {
} break;
case NOTIFICATION_LOCAL_TRANSFORM_CHANGED: {
if (!can_update_body && shape_from>=0 && shape_from>=0) {
if (!can_update_body && shape_from>=0 && shape_to>=0) {
CollisionObject *co = get_parent()->cast_to<CollisionObject>();
if (co) {

View File

@ -2713,6 +2713,21 @@ void Control::warp_mouse(const Point2& p_to_pos) {
get_viewport()->warp_mouse(get_global_transform().xform(p_to_pos));
}
bool Control::is_text_field() const {
/*
if (get_script_instance()) {
Variant v=p_point;
const Variant *p[2]={&v,&p_data};
Variant::CallError ce;
Variant ret = get_script_instance()->call("is_text_field",p,2,ce);
if (ce.error==Variant::CallError::CALL_OK)
return ret;
}
*/
return false;
}
void Control::_bind_methods() {
ObjectTypeDB::bind_method(_MD("_window_input_event"),&Control::_window_input_event);

View File

@ -382,6 +382,8 @@ public:
void warp_mouse(const Point2& p_to_pos);
virtual bool is_text_field() const;
Control();
~Control();

View File

@ -782,6 +782,10 @@ void LineEdit::select(int p_from, int p_to) {
update();
}
bool LineEdit::is_text_field() const {
return true;
}
void LineEdit::_bind_methods() {

View File

@ -112,6 +112,8 @@ public:
void select(int p_from=0, int p_to=-1);
virtual Size2 get_minimum_size() const;
virtual bool is_text_field() const;
LineEdit();
~LineEdit();

View File

@ -323,8 +323,10 @@ void PopupMenu::_input_event(const InputEvent &p_event) {
invalidated_click=false;
break;
}
if (over<0 || items[over].separator || items[over].disabled)
if (over<0 || items[over].separator || items[over].disabled) {
hide();
break; //non-activable
}
if (items[over].submenu!="") {
@ -738,10 +740,18 @@ int PopupMenu::find_item_by_accelerator(uint32_t p_accel) const {
void PopupMenu::activate_item(int p_item) {
ERR_FAIL_INDEX(p_item,items.size());
ERR_FAIL_COND(items[p_item].separator);
emit_signal("item_pressed",items[p_item].ID);
//hide all parent PopupMenue's
Node *next = get_parent();
PopupMenu *pop = next->cast_to<PopupMenu>();
while (pop) {
pop->hide();
next = next->get_parent();
pop = next->cast_to<PopupMenu>();
}
hide();
}

View File

@ -1503,10 +1503,10 @@ Error RichTextLabel::append_bbcode(const String& p_bbcode) {
void RichTextLabel::scroll_to_line(int p_line) {
p_line -= 1;
ERR_FAIL_INDEX(p_line,lines.size());
_validate_line_caches();
vscroll->set_val(lines[p_line].height_accum_cache);
vscroll->set_val(lines[p_line].height_accum_cache-lines[p_line].height_cache);
}
@ -1569,27 +1569,23 @@ bool RichTextLabel::search(const String& p_string,bool p_from_selection) {
it=_get_next_item(it);
}
if (!it)
line=lines.size()-1;
}
scroll_to_line(line-2);
if (line > 1) {
line-=1;
}
scroll_to_line(line);
return true;
}
} else if (it->type==ITEM_NEWLINE) {
line=static_cast<ItemNewline*>(it)->line;
}
it=_get_next_item(it);
charidx=0;
}
return false;
}

View File

@ -64,6 +64,15 @@ Size2 Tabs::get_minimum_size() const {
ms.width+=bms.width;
ms.height=MAX(bms.height+tab_bg->get_minimum_size().height,ms.height);
}
if (tabs[i].close_button.is_valid()) {
Ref<Texture> cb=tabs[i].close_button;
Size2 bms = cb->get_size()+get_stylebox("button")->get_minimum_size();
bms.width+=get_constant("hseparation");
ms.width+=bms.width;
ms.height=MAX(bms.height+tab_bg->get_minimum_size().height,ms.height);
}
}
return ms;
@ -77,22 +86,48 @@ void Tabs::_input_event(const InputEvent& p_event) {
Point2 pos( p_event.mouse_motion.x, p_event.mouse_motion.y );
int hover=-1;
int hover_buttons=-1;
hover=-1;
for(int i=0;i<tabs.size();i++) {
// test hovering tab to display close button if policy says so
if (cb_displaypolicy == SHOW_HOVER) {
int ofs=tabs[i].ofs_cache;
int size = tabs[i].ofs_cache;
if (pos.x >=tabs[i].ofs_cache && pos.x<tabs[i].ofs_cache+tabs[i].size_cache) {
hover=i;
}
}
// test hovering right button and close button
if (tabs[i].rb_rect.has_point(pos)) {
hover=i;
rb_hover=i;
hover_buttons = i;
break;
}
else if (tabs[i].cb_rect.has_point(pos)) {
cb_hover=i;
hover_buttons = i;
break;
}
}
if (hover!=rb_hover) {
rb_hover=hover;
update();
if (hover_buttons == -1) { // no hover
rb_hover= hover_buttons;
cb_hover= hover_buttons;
}
update();
return;
}
if (rb_pressing && p_event.type==InputEvent::MOUSE_BUTTON &&
!p_event.mouse_button.pressed &&
p_event.mouse_button.button_index==BUTTON_LEFT) {
@ -106,6 +141,20 @@ void Tabs::_input_event(const InputEvent& p_event) {
update();
}
if (cb_pressing && p_event.type==InputEvent::MOUSE_BUTTON &&
!p_event.mouse_button.pressed &&
p_event.mouse_button.button_index==BUTTON_LEFT) {
if (cb_hover!=-1) {
//pressed
emit_signal("tab_close",cb_hover);
}
cb_pressing=false;
update();
}
if (p_event.type==InputEvent::MOUSE_BUTTON &&
p_event.mouse_button.pressed &&
p_event.mouse_button.button_index==BUTTON_LEFT) {
@ -122,6 +171,12 @@ void Tabs::_input_event(const InputEvent& p_event) {
return;
}
if (tabs[i].cb_rect.has_point(pos)) {
cb_pressing=true;
update();
return;
}
int ofs=tabs[i].ofs_cache;
int size = tabs[i].ofs_cache;
if (pos.x >=tabs[i].ofs_cache && pos.x<tabs[i].ofs_cache+tabs[i].size_cache) {
@ -148,6 +203,8 @@ void Tabs::_notification(int p_what) {
case NOTIFICATION_MOUSE_EXIT: {
rb_hover=-1;
cb_hover=-1;
hover=-1;
update();
} break;
case NOTIFICATION_DRAW: {
@ -186,7 +243,7 @@ void Tabs::_notification(int p_what) {
String s = tabs[i].text;
int lsize=0;
int slen=font->get_string_size(s).width;;
int slen=font->get_string_size(s).width;
lsize+=slen;
Ref<Texture> icon;
@ -211,6 +268,56 @@ void Tabs::_notification(int p_what) {
}
// Close button
switch (cb_displaypolicy) {
case SHOW_ALWAYS: {
if (tabs[i].close_button.is_valid()) {
Ref<StyleBox> style = get_stylebox("button");
Ref<Texture> rb=tabs[i].close_button;
lsize+=get_constant("hseparation");
lsize+=style->get_margin(MARGIN_LEFT);
lsize+=rb->get_width();
lsize+=style->get_margin(MARGIN_RIGHT);
}
} break;
case SHOW_ACTIVE_ONLY: {
if (i==current) {
if (tabs[i].close_button.is_valid()) {
Ref<StyleBox> style = get_stylebox("button");
Ref<Texture> rb=tabs[i].close_button;
lsize+=get_constant("hseparation");
lsize+=style->get_margin(MARGIN_LEFT);
lsize+=rb->get_width();
lsize+=style->get_margin(MARGIN_RIGHT);
}
}
} break;
case SHOW_HOVER: {
if (i==current || i==hover) {
if (tabs[i].close_button.is_valid()) {
Ref<StyleBox> style = get_stylebox("button");
Ref<Texture> rb=tabs[i].close_button;
lsize+=get_constant("hseparation");
lsize+=style->get_margin(MARGIN_LEFT);
lsize+=rb->get_width();
lsize+=style->get_margin(MARGIN_RIGHT);
}
}
} break;
case SHOW_NEVER: // by default, never show close button
default: {
// do nothing
} break;
}
Ref<StyleBox> sb;
int va;
Color col;
@ -273,6 +380,103 @@ void Tabs::_notification(int p_what) {
}
// Close button
switch (cb_displaypolicy) {
case SHOW_ALWAYS: {
if (tabs[i].close_button.is_valid()) {
Ref<StyleBox> style = get_stylebox("button");
Ref<Texture> cb=tabs[i].close_button;
w+=get_constant("hseparation");
Rect2 cb_rect;
cb_rect.size=style->get_minimum_size()+cb->get_size();
cb_rect.pos.x=w;
cb_rect.pos.y=sb->get_margin(MARGIN_TOP)+((sb_rect.size.y-sb_ms.y)-(cb_rect.size.y))/2;
if (cb_hover==i) {
if (cb_pressing)
get_stylebox("button_pressed")->draw(ci,cb_rect);
else
style->draw(ci,cb_rect);
}
w+=style->get_margin(MARGIN_LEFT);
cb->draw(ci,Point2i( w,cb_rect.pos.y+style->get_margin(MARGIN_TOP) ));
w+=cb->get_width();
w+=style->get_margin(MARGIN_RIGHT);
tabs[i].cb_rect=cb_rect;
}
} break;
case SHOW_ACTIVE_ONLY: {
if (current==i) {
if (tabs[i].close_button.is_valid()) {
Ref<StyleBox> style = get_stylebox("button");
Ref<Texture> cb=tabs[i].close_button;
w+=get_constant("hseparation");
Rect2 cb_rect;
cb_rect.size=style->get_minimum_size()+cb->get_size();
cb_rect.pos.x=w;
cb_rect.pos.y=sb->get_margin(MARGIN_TOP)+((sb_rect.size.y-sb_ms.y)-(cb_rect.size.y))/2;
if (cb_hover==i) {
if (cb_pressing)
get_stylebox("button_pressed")->draw(ci,cb_rect);
else
style->draw(ci,cb_rect);
}
w+=style->get_margin(MARGIN_LEFT);
cb->draw(ci,Point2i( w,cb_rect.pos.y+style->get_margin(MARGIN_TOP) ));
w+=cb->get_width();
w+=style->get_margin(MARGIN_RIGHT);
tabs[i].cb_rect=cb_rect;
}
}
} break;
case SHOW_HOVER: {
if (current==i || hover==i) {
if (tabs[i].close_button.is_valid()) {
Ref<StyleBox> style = get_stylebox("button");
Ref<Texture> cb=tabs[i].close_button;
w+=get_constant("hseparation");
Rect2 cb_rect;
cb_rect.size=style->get_minimum_size()+cb->get_size();
cb_rect.pos.x=w;
cb_rect.pos.y=sb->get_margin(MARGIN_TOP)+((sb_rect.size.y-sb_ms.y)-(cb_rect.size.y))/2;
if (cb_hover==i) {
if (cb_pressing)
get_stylebox("button_pressed")->draw(ci,cb_rect);
else
style->draw(ci,cb_rect);
}
w+=style->get_margin(MARGIN_LEFT);
cb->draw(ci,Point2i( w,cb_rect.pos.y+style->get_margin(MARGIN_TOP) ));
w+=cb->get_width();
w+=style->get_margin(MARGIN_RIGHT);
tabs[i].cb_rect=cb_rect;
}
}
} break;
case SHOW_NEVER:
default: {
// show nothing
} break;
}
w+=sb->get_margin(MARGIN_RIGHT);
tabs[i].size_cache=w-tabs[i].ofs_cache;
@ -358,11 +562,29 @@ Ref<Texture> Tabs::get_tab_right_button(int p_tab) const{
}
void Tabs::set_tab_close_button(int p_tab, const Ref<Texture>& p_close_button) {
ERR_FAIL_INDEX(p_tab, tabs.size());
tabs[p_tab].close_button=p_close_button;
update();
minimum_size_changed();
}
Ref<Texture> Tabs::get_tab_close_button(int p_tab) const{
ERR_FAIL_INDEX_V(p_tab,tabs.size(),Ref<Texture>());
return tabs[p_tab].close_button;
}
void Tabs::add_tab(const String& p_str,const Ref<Texture>& p_icon) {
Tab t;
t.text=p_str;
t.icon=p_icon;
t.close_button = get_icon("Close","EditorIcons");
tabs.push_back(t);
update();
@ -394,6 +616,11 @@ void Tabs::remove_tab(int p_idx) {
}
void Tabs::set_tab_close_display_policy(CloseButtonDisplayPolicy p_cb_displaypolicy) {
cb_displaypolicy = p_cb_displaypolicy;
}
void Tabs::set_tab_align(TabAlign p_align) {
tab_align=p_align;
@ -423,14 +650,22 @@ void Tabs::_bind_methods() {
ADD_SIGNAL(MethodInfo("tab_changed",PropertyInfo(Variant::INT,"tab")));
ADD_SIGNAL(MethodInfo("right_button_pressed",PropertyInfo(Variant::INT,"tab")));
ADD_SIGNAL(MethodInfo("tab_close",PropertyInfo(Variant::INT,"tab")));
ADD_PROPERTY( PropertyInfo(Variant::INT, "current_tab", PROPERTY_HINT_RANGE,"-1,4096,1",PROPERTY_USAGE_EDITOR), _SCS("set_current_tab"), _SCS("get_current_tab") );
BIND_CONSTANT( ALIGN_LEFT );
BIND_CONSTANT( ALIGN_CENTER );
BIND_CONSTANT( ALIGN_RIGHT );
BIND_CONSTANT( SHOW_ACTIVE_ONLY );
BIND_CONSTANT( SHOW_ALWAYS );
BIND_CONSTANT( SHOW_HOVER );
BIND_CONSTANT( SHOW_NEVER );
}
Tabs::Tabs() {
current=0;
@ -438,4 +673,7 @@ Tabs::Tabs() {
rb_hover=-1;
rb_pressing=false;
cb_hover=-1;
cb_pressing=false;
cb_displaypolicy = SHOW_NEVER; // Default : no close button
}

View File

@ -42,6 +42,14 @@ public:
ALIGN_CENTER,
ALIGN_RIGHT
};
enum CloseButtonDisplayPolicy {
SHOW_ALWAYS,
SHOW_ACTIVE_ONLY,
SHOW_HOVER,
SHOW_NEVER
};
private:
@ -53,6 +61,8 @@ private:
int size_cache;
Ref<Texture> right_button;
Rect2 rb_rect;
Ref<Texture> close_button;
Rect2 cb_rect;
};
Vector<Tab> tabs;
@ -63,6 +73,12 @@ private:
int rb_hover;
bool rb_pressing;
int cb_hover;
bool cb_pressing;
CloseButtonDisplayPolicy cb_displaypolicy;
int hover; // hovered tab
protected:
void _input_event(const InputEvent& p_event);
@ -82,6 +98,10 @@ public:
void set_tab_right_button(int p_tab,const Ref<Texture>& p_right_button);
Ref<Texture> get_tab_right_button(int p_tab) const;
void set_tab_close_button(int p_tab, const Ref<Texture>& p_close_button);
Ref<Texture> get_tab_close_button(int p_tab) const;
void set_tab_close_display_policy(CloseButtonDisplayPolicy p_cb_displaypolicy);
void set_tab_align(TabAlign p_align);
TabAlign get_tab_align() const;

View File

@ -709,7 +709,7 @@ void TextEdit::_notification(int p_what) {
if (in_region==-1 && !in_keyword && is_char && !prev_is_char) {
int to=j;
while(_is_text_char(str[to]) && to<str.length())
while(to<str.length() && _is_text_char(str[to]))
to++;
uint32_t hash = String::hash(&str[j],to-j);
@ -3568,7 +3568,10 @@ void TextEdit::set_show_line_numbers(bool p_show) {
update();
}
bool TextEdit::is_text_field() const {
return true;
}
void TextEdit::_bind_methods() {

View File

@ -393,6 +393,7 @@ public:
String get_text_for_completion();
virtual bool is_text_field() const;
TextEdit();
~TextEdit();
};

View File

@ -1993,7 +1993,7 @@ void Node::_bind_methods() {
ObjectTypeDB::bind_method(_MD("has_node","path"),&Node::has_node);
ObjectTypeDB::bind_method(_MD("get_node:Node","path"),&Node::get_node);
ObjectTypeDB::bind_method(_MD("get_parent:Parent"),&Node::get_parent);
ObjectTypeDB::bind_method(_MD("find_node:Node","mask","recursive","owned"),&Node::get_node,DEFVAL(true),DEFVAL(true));
ObjectTypeDB::bind_method(_MD("find_node:Node","mask","recursive","owned"),&Node::find_node,DEFVAL(true),DEFVAL(true));
ObjectTypeDB::bind_method(_MD("has_node_and_resource","path"),&Node::has_node_and_resource);
ObjectTypeDB::bind_method(_MD("get_node_and_resource","path"),&Node::_get_node_and_resource);

View File

@ -101,7 +101,7 @@ Node *SceneState::instance(bool p_gen_edit_state) const {
if (i==0 && base_scene_idx>=0) {
//scene inheritance on root node
print_line("scene inherit");
//print_line("scene inherit");
Ref<PackedScene> sdata = props[ base_scene_idx ];
ERR_FAIL_COND_V( !sdata.is_valid(), NULL);
node = sdata->instance(p_gen_edit_state);
@ -112,7 +112,7 @@ Node *SceneState::instance(bool p_gen_edit_state) const {
} else if (n.instance>=0) {
//instance a scene into this node
print_line("instance");
//print_line("instance");
if (n.instance&FLAG_INSTANCE_IS_PLACEHOLDER) {
String path = props[n.instance&FLAG_MASK];
@ -148,7 +148,7 @@ Node *SceneState::instance(bool p_gen_edit_state) const {
#endif
}
} else if (ObjectTypeDB::is_type_enabled(snames[n.type])) {
print_line("created");
//print_line("created");
//node belongs to this scene and must be created
Object * obj = ObjectTypeDB::instance(snames[ n.type ]);
if (!obj || !obj->cast_to<Node>()) {

View File

@ -194,7 +194,6 @@ bool BodyPairSW::_test_ccd(float p_step,BodySW *p_A, int p_shape_A,const Transfo
//cast a segment from support in motion normal, in the same direction of motion by motion length
//support is the worst case collision point, so real collision happened before
int a;
Vector3 s=p_A->get_shape(p_shape_A)->get_support(p_xform_A.basis.xform(mnormal).normalized());
Vector3 from = p_xform_A.xform(s);
Vector3 to = from + motion;

View File

@ -34,10 +34,10 @@
_FORCE_INLINE_ static bool _match_object_type_query(CollisionObjectSW *p_object, uint32_t p_layer_mask, uint32_t p_type_mask) {
if ((p_object->get_layer_mask()&p_layer_mask)==0)
return false;
if (p_object->get_type()==CollisionObjectSW::TYPE_AREA)
return p_type_mask&PhysicsDirectSpaceState::TYPE_MASK_AREA;
if (p_object->get_type()==CollisionObjectSW::TYPE_AREA && !(p_type_mask&PhysicsDirectSpaceState::TYPE_MASK_AREA))
if ((p_object->get_layer_mask()&p_layer_mask)==0)
return false;
BodySW *body = static_cast<BodySW*>(p_object);

View File

@ -279,6 +279,18 @@ void PinJoint2DSW::solve(float p_step){
P += impulse;
}
void PinJoint2DSW::set_param(Physics2DServer::PinJointParam p_param, real_t p_value) {
if(p_param == Physics2DServer::PIN_JOINT_SOFTNESS)
softness = p_value;
}
real_t PinJoint2DSW::get_param(Physics2DServer::PinJointParam p_param) const {
if(p_param == Physics2DServer::PIN_JOINT_SOFTNESS)
return softness;
ERR_FAIL_V(0);
}
PinJoint2DSW::PinJoint2DSW(const Vector2& p_pos,Body2DSW* p_body_a,Body2DSW* p_body_b) : Joint2DSW(_arr,p_body_b?2:1) {

View File

@ -121,6 +121,8 @@ public:
virtual bool setup(float p_step);
virtual void solve(float p_step);
void set_param(Physics2DServer::PinJointParam p_param, real_t p_value);
real_t get_param(Physics2DServer::PinJointParam p_param) const;
PinJoint2DSW(const Vector2& p_pos,Body2DSW* p_body_a,Body2DSW* p_body_b=NULL);
~PinJoint2DSW();

View File

@ -1096,6 +1096,25 @@ RID Physics2DServerSW::damped_spring_joint_create(const Vector2& p_anchor_a,cons
}
void Physics2DServerSW::pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value) {
Joint2DSW *j = joint_owner.get(p_joint);
ERR_FAIL_COND(!j);
ERR_FAIL_COND(j->get_type()!=JOINT_PIN);
PinJoint2DSW *pin_joint = static_cast<PinJoint2DSW*>(j);
pin_joint->set_param(p_param, p_value);
}
real_t Physics2DServerSW::pin_joint_get_param(RID p_joint, PinJointParam p_param) const {
Joint2DSW *j = joint_owner.get(p_joint);
ERR_FAIL_COND_V(!j,0);
ERR_FAIL_COND_V(j->get_type()!=JOINT_PIN,0);
PinJoint2DSW *pin_joint = static_cast<PinJoint2DSW*>(j);
return pin_joint->get_param(p_param);
}
void Physics2DServerSW::damped_string_joint_set_param(RID p_joint, DampedStringParam p_param, real_t p_value) {

View File

@ -243,6 +243,8 @@ public:
virtual RID pin_joint_create(const Vector2& p_pos,RID p_body_a,RID p_body_b=RID());
virtual RID groove_joint_create(const Vector2& p_a_groove1,const Vector2& p_a_groove2, const Vector2& p_b_anchor, RID p_body_a,RID p_body_b);
virtual RID damped_spring_joint_create(const Vector2& p_anchor_a,const Vector2& p_anchor_b,RID p_body_a,RID p_body_b=RID());
virtual void pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value);
virtual real_t pin_joint_get_param(RID p_joint, PinJointParam p_param) const;
virtual void damped_string_joint_set_param(RID p_joint, DampedStringParam p_param, real_t p_value);
virtual real_t damped_string_joint_get_param(RID p_joint, DampedStringParam p_param) const;

View File

@ -258,6 +258,9 @@ public:
FUNC5R(RID,groove_joint_create,const Vector2&,const Vector2&,const Vector2&,RID,RID);
FUNC4R(RID,damped_spring_joint_create,const Vector2&,const Vector2&,RID,RID);
FUNC3(pin_joint_set_param,RID,PinJointParam,real_t);
FUNC2RC(real_t,pin_joint_get_param,RID,PinJointParam);
FUNC3(damped_string_joint_set_param,RID,DampedStringParam,real_t);
FUNC2RC(real_t,damped_string_joint_get_param,RID,DampedStringParam);

View File

@ -36,8 +36,8 @@ _FORCE_INLINE_ static bool _match_object_type_query(CollisionObject2DSW *p_objec
if ((p_object->get_layer_mask()&p_layer_mask)==0)
return false;
if (p_object->get_type()==CollisionObject2DSW::TYPE_AREA && !(p_type_mask&Physics2DDirectSpaceState::TYPE_MASK_AREA))
return false;
if (p_object->get_type()==CollisionObject2DSW::TYPE_AREA)
return p_type_mask&Physics2DDirectSpaceState::TYPE_MASK_AREA;
Body2DSW *body = static_cast<Body2DSW*>(p_object);

View File

@ -516,6 +516,13 @@ public:
virtual RID groove_joint_create(const Vector2& p_a_groove1,const Vector2& p_a_groove2, const Vector2& p_b_anchor, RID p_body_a,RID p_body_b)=0;
virtual RID damped_spring_joint_create(const Vector2& p_anchor_a,const Vector2& p_anchor_b,RID p_body_a,RID p_body_b=RID())=0;
enum PinJointParam {
PIN_JOINT_SOFTNESS
};
virtual void pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value)=0;
virtual real_t pin_joint_get_param(RID p_joint, PinJointParam p_param) const=0;
enum DampedStringParam {
DAMPED_STRING_REST_LENGTH,
DAMPED_STRING_STIFFNESS,

View File

@ -1375,7 +1375,7 @@ void VisualServerRaster::_update_baked_light_sampler_dp_cache(BakedLightSampler
void VisualServerRaster::baked_light_sampler_set_resolution(RID p_baked_light_sampler,int p_resolution){
ERR_FAIL_COND(p_resolution<4 && p_resolution>64);
ERR_FAIL_COND(p_resolution<4 || p_resolution>64);
VS_CHANGED;
BakedLightSampler * blsamp = baked_light_sampler_owner.get(p_baked_light_sampler);
ERR_FAIL_COND(!blsamp);
@ -5219,7 +5219,6 @@ void VisualServerRaster::_light_instance_update_lispsm_shadow(Instance *p_light,
AABB proj_space_aabb;
float max_d,min_d;
{
@ -6824,7 +6823,11 @@ void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Mat
copymem(child_items,ci->child_items.ptr(),child_item_count*sizeof(CanvasItem*));
if (ci->clip) {
ci->final_clip_rect=global_rect;
if (p_canvas_clip != NULL) {
ci->final_clip_rect=p_canvas_clip->final_clip_rect.clip(global_rect);
} else {
ci->final_clip_rect=global_rect;
}
ci->final_clip_owner=ci;
} else {

Binary file not shown.

View File

@ -0,0 +1,142 @@
# Translations template for PROJECT.
# Copyright (C) 2015 ORGANIZATION
# This file is distributed under the same license as the PROJECT project.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2015.
#
msgid ""
msgstr ""
"Project-Id-Version: makedocs\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2015-10-07 11:47-0600\n"
"PO-Revision-Date: 2015-10-07 13:10-0600\n"
"Last-Translator: Jorge Araya Navarro <elcorreo@deshackra.com>\n"
"Language-Team: \n"
"Language: es\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.0\n"
"X-Generator: Poedit 1.8.4\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: makedocs.py:74
msgid ""
"\"<code>{gclass}</code>(Go to page of class {gclass})\":/class_{lkclass}"
msgstr ""
"\"<code>{gclass}</code>(Ir a la pagina de la clase {gclass})\":/"
"class_{lkclass}"
#: makedocs.py:76
msgid ""
"\"<code>{gclass}.{method}</code>(Go to page {gclass}, section {method})\":/"
"class_{lkclass}#{lkmethod}"
msgstr ""
"\"<code>{gclass}.{method}</code>(Ir a la pagina {gclass}, sección "
"{method})\":/class_{lkclass}#{lkmethod}"
#: makedocs.py:79
msgid "\"<code>{method}</code>(Jump to method {method})\":#{lkmethod}"
msgstr "\"<code>{method}</code>(Saltar al método {method})\":#{lkmethod}"
#: makedocs.py:81
msgid " \"{rtype}(Go to page of class {rtype})\":/class_{link} "
msgstr " \"{rtype}(Ir a la pagina de la clase {rtype})\":/class_{link} "
#: makedocs.py:82
msgid ""
"\"*{funcname}*(Jump to description for node {funcname})\":#{link} <b>(</b> "
msgstr ""
"\"*{funcname}*(Saltar a la descripción para el nodo {funcname})\":#{link} "
"<b>(</b> "
#: makedocs.py:87
msgid "h4. Inherits: "
msgstr "h4. Hereda de: "
#: makedocs.py:232
msgid "<doc>'s version attribute missing"
msgstr "El atributo version de <doc> no existe"
#: makedocs.py:246
msgid "|_. Index symbol |_. Class name |_. Index symbol |_. Class name |\n"
msgstr ""
"|_. Índice de símbolo |_. Nombre de la clase |_. Índice de símbolo |_. "
"Nombre de la clase |\n"
#: makedocs.py:305
msgid ""
"h4. Category: {}\n"
"\n"
msgstr ""
"h4. Categoría: {}\n"
"\n"
#: makedocs.py:310
msgid ""
"h2. Brief Description\n"
"\n"
msgstr ""
"h2. Descripción breve\n"
"\n"
#: makedocs.py:312
msgid ""
"\"read more\":#more\n"
"\n"
msgstr ""
"\"Leer más\":#more\n"
"\n"
#: makedocs.py:317
msgid ""
"\n"
"h3. Member Functions\n"
"\n"
msgstr ""
"\n"
"h3. Funciones miembro\n"
"\n"
#: makedocs.py:323
msgid ""
"\n"
"h3. Signals\n"
"\n"
msgstr ""
"\n"
"h3. Señales\n"
"\n"
#: makedocs.py:331
msgid ""
"\n"
"h3. Numeric Constants\n"
"\n"
msgstr ""
"\n"
"h3. Constantes numéricas\n"
"\n"
#: makedocs.py:347
msgid ""
"\n"
"h3(#more). Description\n"
"\n"
msgstr ""
"\n"
"h3(#more). Descripción\n"
"\n"
#: makedocs.py:351
msgid "_Nothing here, yet..._\n"
msgstr "_Aún nada por aquí..._\n"
#: makedocs.py:355
msgid ""
"\n"
"h3. Member Function Description\n"
"\n"
msgstr ""
"\n"
"h3. Descripción de las funciones miembro\n"
"\n"

108
tools/docdump/makedocs.pot Normal file
View File

@ -0,0 +1,108 @@
# Translations template for PROJECT.
# Copyright (C) 2015 ORGANIZATION
# This file is distributed under the same license as the PROJECT project.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2015.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: makedocs 0.1\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2015-10-07 11:47-0600\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.0\n"
"X-Generator: Poedit 1.8.4\n"
#: makedocs.py:74
msgid "\"<code>{gclass}</code>(Go to page of class {gclass})\":/class_{lkclass}"
msgstr ""
#: makedocs.py:76
msgid "\"<code>{gclass}.{method}</code>(Go to page {gclass}, section {method})\":/class_{lkclass}#{lkmethod}"
msgstr ""
#: makedocs.py:79
msgid "\"<code>{method}</code>(Jump to method {method})\":#{lkmethod}"
msgstr ""
#: makedocs.py:81
msgid " \"{rtype}(Go to page of class {rtype})\":/class_{link} "
msgstr ""
#: makedocs.py:82
msgid "\"*{funcname}*(Jump to description for node {funcname})\":#{link} <b>(</b> "
msgstr ""
#: makedocs.py:87
msgid "h4. Inherits: "
msgstr ""
#: makedocs.py:232
msgid "<doc>'s version attribute missing"
msgstr ""
#: makedocs.py:246
msgid "|_. Index symbol |_. Class name |_. Index symbol |_. Class name |\n"
msgstr ""
#: makedocs.py:305
msgid ""
"h4. Category: {}\n"
"\n"
msgstr ""
#: makedocs.py:310
msgid ""
"h2. Brief Description\n"
"\n"
msgstr ""
#: makedocs.py:312
msgid ""
"\"read more\":#more\n"
"\n"
msgstr ""
#: makedocs.py:317
msgid ""
"\n"
"h3. Member Functions\n"
"\n"
msgstr ""
#: makedocs.py:323
msgid ""
"\n"
"h3. Signals\n"
"\n"
msgstr ""
#: makedocs.py:331
msgid ""
"\n"
"h3. Numeric Constants\n"
"\n"
msgstr ""
#: makedocs.py:347
msgid ""
"\n"
"h3(#more). Description\n"
"\n"
msgstr ""
#: makedocs.py:351
msgid "_Nothing here, yet..._\n"
msgstr ""
#: makedocs.py:355
msgid ""
"\n"
"h3. Member Function Description\n"
"\n"
msgstr ""

382
tools/docdump/makedocs.py Normal file
View File

@ -0,0 +1,382 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
#
# makedocs.py: Generate documentation for Open Project Wiki
# Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur.
# Contributor: Jorge Araya Navarro <elcorreo@deshackra.com>
#
# IMPORTANT NOTICE:
# If you are going to modify anything from this file, please be sure to follow
# the Style Guide for Python Code or often called "PEP8". To do this
# automagically just install autopep8:
#
# $ sudo pip3 install autopep8
#
# and run:
#
# $ autopep8 makedocs.py
#
# Before committing your changes. Also be sure to delete any trailing
# whitespace you may left.
#
# TODO:
# * Refactor code.
# * Adapt this script for generating content in other markup formats like
# DokuWiki, Markdown, etc.
#
# Also check other TODO entries in this script for more information on what is
# left to do.
import argparse
import gettext
import logging
import re
from itertools import zip_longest
from os import path, listdir
from xml.etree import ElementTree
# add an option to change the verbosity
logging.basicConfig(level=logging.INFO)
def getxmlfloc():
""" Returns the supposed location of the XML file
"""
filepath = path.dirname(path.abspath(__file__))
return path.join(filepath, "class_list.xml")
def langavailable():
""" Return a list of languages available for translation
"""
filepath = path.join(
path.dirname(path.abspath(__file__)), "locales")
files = listdir(filepath)
choices = [x for x in files]
choices.insert(0, "none")
return choices
desc = "Generates documentation from a XML file to different markup languages"
parser = argparse.ArgumentParser(description=desc)
parser.add_argument("--input", dest="xmlfp", default=getxmlfloc(),
help="Input XML file, default: {}".format(getxmlfloc()))
parser.add_argument("--output-dir", dest="outputdir", required=True,
help="Output directory for generated files")
parser.add_argument("--language", choices=langavailable(), default="none",
help=("Choose the language of translation"
" for the output files. Default is English (none). "
"Note: This is NOT for the documentation itself!"))
# TODO: add an option for outputting different markup formats
args = parser.parse_args()
# Let's check if the file and output directory exists
if not path.isfile(args.xmlfp):
logging.critical("File not found: {}".format(args.xmlfp))
exit(1)
elif not path.isdir(args.outputdir):
logging.critical("Path does not exist: {}".format(args.outputdir))
exit(1)
_ = gettext.gettext
if args.language != "none":
lang = gettext.translation(domain="makedocs",
localedir="locales",
languages=[args.language])
lang.install()
_ = lang.gettext
# Strings
C_LINK = _("\"<code>{gclass}</code>(Go to page of class"
" {gclass})\":/class_{lkclass}")
MC_LINK = _("\"<code>{gclass}.{method}</code>(Go "
"to page {gclass}, section {method})\""
":/class_{lkclass}#{lkmethod}")
TM_JUMP = _("\"<code>{method}</code>(Jump to method"
" {method})\":#{lkmethod}")
GTC_LINK = _(" \"{rtype}(Go to page of class {rtype})\":/class_{link} ")
DFN_JUMP = _("\"*{funcname}*(Jump to description for"
" node {funcname})\":#{link} <b>(</b> ")
M_ARG_DEFAULT = C_LINK + " {name}={default}"
M_ARG = C_LINK + " {name}"
OPENPROJ_INH = _("h4. Inherits: ") + C_LINK + "\n\n"
def tb(string):
""" Return a byte representation of a string
"""
return bytes(string, "UTF-8")
def sortkey(c):
""" Symbols are first, letters second
"""
if "_" == c.attrib["name"][0]:
return "A"
else:
return c.attrib["name"]
def toOP(text):
""" Convert commands in text to Open Project commands
"""
# TODO: Make this capture content between [command] ... [/command]
groups = re.finditer((r'\[html (?P<command>/?\w+/?)(\]| |=)?(\]| |=)?(?P<a'
'rg>\w+)?(\]| |=)?(?P<value>"[^"]+")?/?\]'), text)
alignstr = ""
for group in groups:
gd = group.groupdict()
if gd["command"] == "br/":
text = text.replace(group.group(0), "\n\n", 1)
elif gd["command"] == "div":
if gd["value"] == '"center"':
alignstr = ("{display:block; margin-left:auto;"
" margin-right:auto;}")
elif gd["value"] == '"left"':
alignstr = "<"
elif gd["value"] == '"right"':
alignstr = ">"
text = text.replace(group.group(0), "\n\n", 1)
elif gd["command"] == "/div":
alignstr = ""
text = text.replace(group.group(0), "\n\n", 1)
elif gd["command"] == "img":
text = text.replace(group.group(0), "!{align}{src}!".format(
align=alignstr, src=gd["value"].strip('"')), 1)
elif gd["command"] == "b" or gd["command"] == "/b":
text = text.replace(group.group(0), "*", 1)
elif gd["command"] == "i" or gd["command"] == "/i":
text = text.replace(group.group(0), "_", 1)
elif gd["command"] == "u" or gd["command"] == "/u":
text = text.replace(group.group(0), "+", 1)
# Process other non-html commands
groups = re.finditer((r'\[method ((?P<class>[aA0-zZ9_]+)(?:\.))'
r'?(?P<method>[aA0-zZ9_]+)\]'), text)
for group in groups:
gd = group.groupdict()
if gd["class"]:
replacewith = (MC_LINK.format(gclass=gd["class"],
method=gd["method"],
lkclass=gd["class"].lower(),
lkmethod=gd["method"].lower()))
else:
# The method is located in the same wiki page
replacewith = (TM_JUMP.format(method=gd["method"],
lkmethod=gd["method"].lower()))
text = text.replace(group.group(0), replacewith, 1)
# Finally, [Classes] are around brackets, make them direct links
groups = re.finditer(r'\[(?P<class>[az0-AZ0_]+)\]', text)
for group in groups:
gd = group.groupdict()
replacewith = (C_LINK.
format(gclass=gd["class"],
lkclass=gd["class"].lower()))
text = text.replace(group.group(0), replacewith, 1)
return text + "\n\n"
def mkfn(node, is_signal=False):
""" Return a string containing a unsorted item for a function
"""
finalstr = ""
name = node.attrib["name"]
rtype = node.find("return")
if rtype:
rtype = rtype.attrib["type"]
else:
rtype = "void"
# write the return type and the function name first
finalstr += "* "
# return type
if not is_signal:
if rtype != "void":
finalstr += GTC_LINK.format(
rtype=rtype,
link=rtype.lower())
else:
finalstr += " void "
# function name
if not is_signal:
finalstr += DFN_JUMP.format(
funcname=name,
link=name.lower())
else:
# Signals have no description
finalstr += "*{funcname}* <b>(</b>".format(funcname=name)
# loop for the arguments of the function, if any
args = []
for arg in sorted(
node.iter(tag="argument"),
key=lambda a: int(a.attrib["index"])):
ntype = arg.attrib["type"]
nname = arg.attrib["name"]
if "default" in arg.attrib:
args.insert(-1, M_ARG_DEFAULT.format(
gclass=ntype,
lkclass=ntype.lower(),
name=nname,
default=arg.attrib["default"]))
else:
# No default value present
args.insert(-1, M_ARG.format(gclass=ntype,
lkclass=ntype.lower(), name=nname))
# join the arguments together
finalstr += ", ".join(args)
# and, close the function with a )
finalstr += " <b>)</b>"
# write the qualifier, if any
if "qualifiers" in node.attrib:
qualifier = node.attrib["qualifiers"]
finalstr += " " + qualifier
finalstr += "\n"
return finalstr
# Let's begin
tree = ElementTree.parse(args.xmlfp)
root = tree.getroot()
# Check version attribute exists in <doc>
if "version" not in root.attrib:
logging.critical(_("<doc>'s version attribute missing"))
exit(1)
version = root.attrib["version"]
classes = sorted(root, key=sortkey)
# first column is always longer, second column of classes should be shorter
zclasses = zip_longest(classes[:int(len(classes) / 2 + 1)],
classes[int(len(classes) / 2 + 1):],
fillvalue="")
# We write the class_list file and also each class file at once
with open(path.join(args.outputdir, "class_list.txt"), "wb") as fcl:
# Write header of table
fcl.write(tb("|^.\n"))
fcl.write(tb(_("|_. Index symbol |_. Class name "
"|_. Index symbol |_. Class name |\n")))
fcl.write(tb("|-.\n"))
indexletterl = ""
indexletterr = ""
for gdclassl, gdclassr in zclasses:
# write a row #
# write the index symbol column, left
if indexletterl != gdclassl.attrib["name"][0]:
indexletterl = gdclassl.attrib["name"][0]
fcl.write(tb("| *{}* |".format(indexletterl.upper())))
else:
# empty cell
fcl.write(tb("| |"))
# write the class name column, left
fcl.write(tb(C_LINK.format(
gclass=gdclassl.attrib["name"],
lkclass=gdclassl.attrib["name"].lower())))
# write the index symbol column, right
if isinstance(gdclassr, ElementTree.Element):
if indexletterr != gdclassr.attrib["name"][0]:
indexletterr = gdclassr.attrib["name"][0]
fcl.write(tb("| *{}* |".format(indexletterr.upper())))
else:
# empty cell
fcl.write(tb("| |"))
# We are dealing with an empty string
else:
# two empty cell
fcl.write(tb("| | |\n"))
# We won't get the name of the class since there is no ElementTree
# object for the right side of the tuple, so we iterate the next
# tuple instead
continue
# write the class name column (if any), right
fcl.write(tb(C_LINK.format(
gclass=gdclassl.attrib["name"],
lkclass=gdclassl.attrib["name"].lower()) + "|\n"))
# row written #
# now, let's write each class page for each class
for gdclass in [gdclassl, gdclassr]:
if not isinstance(gdclass, ElementTree.Element):
continue
classname = gdclass.attrib["name"]
with open(path.join(args.outputdir, "{}.txt".format(
classname.lower())), "wb") as clsf:
# First level header with the name of the class
clsf.write(tb("h1. {}\n\n".format(classname)))
# lay the attributes
if "inherits" in gdclass.attrib:
inh = gdclass.attrib["inherits"].strip()
clsf.write(tb(OPENPROJ_INH.format(gclass=inh,
lkclass=inh.lower())))
if "category" in gdclass.attrib:
clsf.write(tb(_("h4. Category: {}\n\n").
format(gdclass.attrib["category"].strip())))
# lay child nodes
briefd = gdclass.find("brief_description")
if briefd.text.strip():
clsf.write(tb(_("h2. Brief Description\n\n")))
clsf.write(tb(toOP(briefd.text.strip()) +
_("\"read more\":#more\n\n")))
# Write the list of member functions of this class
methods = gdclass.find("methods")
if methods and len(methods) > 0:
clsf.write(tb(_("\nh3. Member Functions\n\n")))
for method in methods.iter(tag='method'):
clsf.write(tb(mkfn(method)))
signals = gdclass.find("signals")
if signals and len(signals) > 0:
clsf.write(tb(_("\nh3. Signals\n\n")))
for signal in signals.iter(tag='signal'):
clsf.write(tb(mkfn(signal, True)))
# TODO: <members> tag is necessary to process? it does not
# exists in class_list.xml file.
consts = gdclass.find("constants")
if consts and len(consts) > 0:
clsf.write(tb(_("\nh3. Numeric Constants\n\n")))
for const in sorted(consts, key=lambda k:
k.attrib["name"]):
if const.text.strip():
clsf.write(tb("* *{name}* = *{value}* - {desc}\n".
format(
name=const.attrib["name"],
value=const.attrib["value"],
desc=const.text.strip())))
else:
# Constant have no description
clsf.write(tb("* *{name}* = *{value}*\n".
format(
name=const.attrib["name"],
value=const.attrib["value"])))
descrip = gdclass.find("description")
clsf.write(tb(_("\nh3(#more). Description\n\n")))
if descrip.text:
clsf.write(tb(descrip.text.strip() + "\n"))
else:
clsf.write(tb(_("_Nothing here, yet..._\n")))
# and finally, the description for each method
if methods and len(methods) > 0:
clsf.write(tb(_("\nh3. Member Function Description\n\n")))
for method in methods.iter(tag='method'):
clsf.write(tb("h4(#{n}). {name}\n\n".format(
n=method.attrib["name"].lower(),
name=method.attrib["name"])))
clsf.write(tb(mkfn(method) + "\n"))
clsf.write(tb(toOP(method.find(
"description").text.strip())))

View File

@ -2369,7 +2369,7 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) {
te->update();
track_editor->set_tooltip("");
if (!track_editor->has_focus() && (!get_focus_owner() || !get_focus_owner()->cast_to<LineEdit>()))
if (!track_editor->has_focus() && (!get_focus_owner() || !get_focus_owner()->is_text_field()))
track_editor->call_deferred("grab_focus");

View File

@ -547,6 +547,7 @@ Error EditorHelp::_goto_desc(const String& p_class,bool p_update_history,int p_v
class_desc->pop();
class_desc->add_newline();
class_desc->add_newline();
class_desc->add_newline();
}
@ -563,6 +564,7 @@ Error EditorHelp::_goto_desc(const String& p_class,bool p_update_history,int p_v
_add_text(cd.brief_description);
class_desc->add_newline();
class_desc->add_newline();
class_desc->add_newline();
}
bool method_descr=false;
@ -637,7 +639,6 @@ Error EditorHelp::_goto_desc(const String& p_class,bool p_update_history,int p_v
if (cd.properties.size()) {
class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/keyword_color"));
class_desc->push_font(doc_title_font);
class_desc->add_text("Members:");
@ -715,9 +716,10 @@ Error EditorHelp::_goto_desc(const String& p_class,bool p_update_history,int p_v
class_desc->add_newline();
}
class_desc->add_newline();
class_desc->pop();
class_desc->add_newline();
class_desc->add_newline();
}
if (cd.signals.size()) {
@ -779,6 +781,7 @@ Error EditorHelp::_goto_desc(const String& p_class,bool p_update_history,int p_v
class_desc->pop();
class_desc->add_newline();
class_desc->add_newline();
}
@ -823,6 +826,7 @@ Error EditorHelp::_goto_desc(const String& p_class,bool p_update_history,int p_v
class_desc->pop();
class_desc->add_newline();
class_desc->add_newline();
}
@ -830,17 +834,18 @@ Error EditorHelp::_goto_desc(const String& p_class,bool p_update_history,int p_v
if (cd.description!="") {
description_line=class_desc->get_line_count()-2;
class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/keyword_color"));
class_desc->push_font(doc_title_font);
class_desc->add_text("Description:");
class_desc->pop();
class_desc->pop();
class_desc->add_newline();
class_desc->add_newline();
_add_text(cd.description);
class_desc->add_newline();
class_desc->add_newline();
class_desc->add_newline();
}
if (method_descr) {
@ -853,12 +858,16 @@ Error EditorHelp::_goto_desc(const String& p_class,bool p_update_history,int p_v
class_desc->add_newline();
class_desc->add_newline();
class_desc->push_indent(1);
for(int i=0;i<cd.methods.size();i++) {
method_line[cd.methods[i].name]=class_desc->get_line_count()-2;
if( cd.methods[i].description != "") {
class_desc->add_newline();
}
class_desc->push_font(doc_code_font);
_add_type(cd.methods[i].return_type);
@ -899,9 +908,12 @@ Error EditorHelp::_goto_desc(const String& p_class,bool p_update_history,int p_v
class_desc->pop();
class_desc->add_newline();
class_desc->add_newline();
_add_text(cd.methods[i].description);
if( cd.methods[i].description != "") {
class_desc->add_text(" ");
_add_text(cd.methods[i].description);
class_desc->add_newline();
class_desc->add_newline();
}
class_desc->add_newline();
class_desc->add_newline();
@ -1392,6 +1404,8 @@ EditorHelp::EditorHelp(EditorNode *p_editor) {
PanelContainer *pc = memnew( PanelContainer );
Ref<StyleBoxFlat> style( memnew( StyleBoxFlat ) );
style->set_bg_color( EditorSettings::get_singleton()->get("text_editor/background_color") );
style->set_default_margin(MARGIN_LEFT,20);
style->set_default_margin(MARGIN_TOP,20);
pc->add_style_override("panel", style); //get_stylebox("normal","TextEdit"));
h_split->add_child(pc);
class_desc = memnew( RichTextLabel );

View File

@ -976,6 +976,7 @@ void EditorNode::_save_scene(String p_file) {
//EditorFileSystem::get_singleton()->update_file(p_file,sdata->get_type());
set_current_version(editor_data.get_undo_redo().get_version());
_update_title();
_update_scene_tabs();
} else {
_dialog_display_file_error(p_file,err);
@ -1399,7 +1400,6 @@ void EditorNode::_dialog_action(String p_file) {
} break;
default: { //save scene?
if (file->get_mode()==FileDialog::MODE_SAVE_FILE) {
//_save_scene(p_file);
@ -3452,6 +3452,9 @@ Error EditorNode::load_scene(const String& p_scene, bool p_ignore_broken_deps,bo
Ref<SceneState> state = sdata->get_state();
state->set_path(lpath);
new_scene->set_scene_inherited_state(state);
new_scene->set_filename(String());
if (new_scene->get_scene_instance_state().is_valid())
new_scene->get_scene_instance_state()->set_path(String());
}
@ -3931,6 +3934,7 @@ void EditorNode::_bind_methods() {
ObjectTypeDB::bind_method("set_current_scene",&EditorNode::set_current_scene);
ObjectTypeDB::bind_method("set_current_version",&EditorNode::set_current_version);
ObjectTypeDB::bind_method("_scene_tab_changed",&EditorNode::_scene_tab_changed);
ObjectTypeDB::bind_method("_scene_tab_closed",&EditorNode::_scene_tab_closed);
ObjectTypeDB::bind_method("_scene_tab_script_edited",&EditorNode::_scene_tab_script_edited);
ObjectTypeDB::bind_method("_set_main_scene_state",&EditorNode::_set_main_scene_state);
ObjectTypeDB::bind_method("_update_scene_tabs",&EditorNode::_update_scene_tabs);
@ -4385,6 +4389,17 @@ void EditorNode::_scene_tab_script_edited(int p_tab) {
edit_resource(script);
}
void EditorNode::_scene_tab_closed(int p_tab) {
set_current_scene(p_tab);
bool p_confirmed = true;
if (unsaved_cache)
p_confirmed = false;
_menu_option_confirm(FILE_CLOSE, p_confirmed);
_update_scene_tabs();
}
void EditorNode::_scene_tab_changed(int p_tab) {
@ -4552,8 +4567,10 @@ EditorNode::EditorNode() {
scene_tabs=memnew( Tabs );
scene_tabs->add_tab("unsaved");
scene_tabs->set_tab_align(Tabs::ALIGN_CENTER);
scene_tabs->set_tab_close_display_policy(Tabs::SHOW_HOVER);
scene_tabs->connect("tab_changed",this,"_scene_tab_changed");
scene_tabs->connect("right_button_pressed",this,"_scene_tab_script_edited");
scene_tabs->connect("tab_close", this, "_scene_tab_closed");
top_dark_vb->add_child(scene_tabs);
//left
left_l_hsplit = memnew( HSplitContainer );
@ -4690,6 +4707,7 @@ EditorNode::EditorNode() {
main_editor_tabs = memnew( Tabs );
main_editor_tabs->connect("tab_changed",this,"_editor_select");
main_editor_tabs->set_tab_close_display_policy(Tabs::SHOW_NEVER);
HBoxContainer *srth = memnew( HBoxContainer );
srt->add_child( srth );
Control *tec = memnew( Control );

View File

@ -501,6 +501,7 @@ class EditorNode : public Node {
void _dock_split_dragged(int ofs);
void _dock_popup_exit();
void _scene_tab_changed(int p_tab);
void _scene_tab_closed(int p_tab);
void _scene_tab_script_edited(int p_tab);
Dictionary _get_main_scene_state();

View File

@ -74,6 +74,7 @@ void EditorPlugin::add_custom_control(CustomControlContainer p_location,Control
case CONTAINER_CANVAS_EDITOR_SIDE: {
CanvasItemEditor::get_singleton()->get_palette_split()->add_child(p_control);
CanvasItemEditor::get_singleton()->get_palette_split()->move_child(p_control,0);
} break;
case CONTAINER_CANVAS_EDITOR_BOTTOM: {

View File

@ -474,6 +474,7 @@ void EditorSettings::_load_defaults() {
set("scenetree_editor/duplicate_node_name_num_separator",0);
hints["scenetree_editor/duplicate_node_name_num_separator"]=PropertyInfo(Variant::INT,"scenetree_editor/duplicate_node_name_num_separator",PROPERTY_HINT_ENUM, "None,Space,Underscore,Dash");
set("gridmap_editor/pick_distance", 5000.0);
set("3d_editor/default_fov",45.0);
set("3d_editor/default_z_near",0.1);

View File

@ -710,7 +710,7 @@ void EditorSampleImportPlugin::_compress_ima_adpcm(const Vector<float>& p_data,D
*(out++) =0;
for (i=0;i<datalen;i++) {
int step,diff,vpdiff,signed_nibble,p,mask;
int step,diff,vpdiff,mask;
uint8_t nibble;
int16_t xm_sample;

View File

@ -144,6 +144,9 @@ void CanvasItemEditor::_unhandled_key_input(const InputEvent& p_ev) {
if (!is_visible())
return;
if (p_ev.key.mod.control)
// prevent to change tool mode when control key is pressed
return;
if (p_ev.key.pressed && !p_ev.key.echo && p_ev.key.scancode==KEY_Q)
_tool_select(TOOL_SELECT);
if (p_ev.key.pressed && !p_ev.key.echo && p_ev.key.scancode==KEY_W)
@ -1281,7 +1284,7 @@ void CanvasItemEditor::_viewport_input_event(const InputEvent& p_event) {
if (p_event.type==InputEvent::MOUSE_MOTION) {
if (!viewport->has_focus())
if (!viewport->has_focus() && (!get_focus_owner() || !get_focus_owner()->is_text_field()))
viewport->call_deferred("grab_focus");
const InputEventMouseMotion &m=p_event.mouse_motion;

View File

@ -25,7 +25,7 @@ Ref<Texture> EditorTexturePreviewPlugin::generate(const RES& p_from) {
if (img.is_compressed()) {
if (img.decompress()!=OK)
return Ref<Texture>();
} else if (img.get_format()!=Image::FORMAT_RGB && img.get_format()!=Image::FORMAT_RGB) {
} else if (img.get_format()!=Image::FORMAT_RGB && img.get_format()!=Image::FORMAT_RGBA) {
img.convert(Image::FORMAT_RGBA);
}

Some files were not shown because too many files have changed in this diff Show More