Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenoit Bolsee <benoit.bolsee@online.be>2012-09-02 01:23:05 +0400
committerBenoit Bolsee <benoit.bolsee@online.be>2012-09-02 01:23:05 +0400
commit53f343edd785f346dccdf39dedfe7626260b63a5 (patch)
treea9c3ac907eae3dd1247168e4cd9dff2760669b27 /source/gameengine
parent779ecb06dd3f3b5c47391675622fb96d041b23ae (diff)
..\commmit_hive.txt
Diffstat (limited to 'source/gameengine')
-rw-r--r--source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp184
-rw-r--r--source/gameengine/GamePlayer/ghost/GPG_ghost.cpp76
-rw-r--r--source/gameengine/Ketsji/CMakeLists.txt2
-rw-r--r--source/gameengine/Ketsji/KX_PythonInit.cpp19
-rw-r--r--source/gameengine/Ketsji/KX_PythonInit.h10
-rw-r--r--source/gameengine/Ketsji/KX_PythonMain.cpp78
-rw-r--r--source/gameengine/Ketsji/KX_PythonMain.h41
7 files changed, 343 insertions, 67 deletions
diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
index 1b8f857c2cb..feec67b509a 100644
--- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
+++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
@@ -54,6 +54,7 @@
#include "KX_BlenderSceneConverter.h"
#include "KX_PythonInit.h"
#include "KX_PyConstraintBinding.h"
+#include "KX_PythonMain.h"
#include "RAS_GLExtensionManager.h"
#include "RAS_OpenGLRasterizer.h"
@@ -79,6 +80,9 @@ extern "C" {
#include "DNA_windowmanager_types.h"
#include "BKE_global.h"
#include "BKE_report.h"
+
+#include "MEM_guardedalloc.h"
+
/* #include "BKE_screen.h" */ /* cant include this because of 'new' function name */
extern float BKE_screen_view3d_zoom_to_fac(float camzoom);
@@ -121,6 +125,95 @@ static BlendFileData *load_game_data(char *filename)
return bfd;
}
+int BL_KetsjiNextFrame(struct KX_KetsjiEngine* ketsjiengine, struct bContext *C, struct wmWindow* win, struct Scene* scene, struct ARegion *ar,
+ KX_BlenderKeyboardDevice* keyboarddevice, KX_BlenderMouseDevice* mousedevice, int draw_letterbox)
+{
+ int exitrequested;
+
+ // first check if we want to exit
+ exitrequested = ketsjiengine->GetExitCode();
+
+ // kick the engine
+ bool render = ketsjiengine->NextFrame();
+
+ if (render)
+ {
+ if(draw_letterbox) {
+ // Clear screen to border color
+ // We do this here since we set the canvas to be within the frames. This means the engine
+ // itself is unaware of the extra space, so we clear the whole region for it.
+ glClearColor(scene->gm.framing.col[0], scene->gm.framing.col[1], scene->gm.framing.col[2], 1.0f);
+ glViewport(ar->winrct.xmin, ar->winrct.ymin,
+ BLI_RCT_SIZE_X(&ar->winrct), BLI_RCT_SIZE_Y(&ar->winrct));
+ glClear(GL_COLOR_BUFFER_BIT);
+ }
+
+ // render the frame
+ ketsjiengine->Render();
+ }
+
+ wm_window_process_events_nosleep();
+
+ // test for the ESC key
+ //XXX while (qtest())
+ while(wmEvent *event= (wmEvent *)win->queue.first)
+ {
+ short val = 0;
+ //unsigned short event = 0; //XXX extern_qread(&val);
+
+ if (keyboarddevice->ConvertBlenderEvent(event->type,event->val))
+ exitrequested = KX_EXIT_REQUEST_BLENDER_ESC;
+
+ /* Coordinate conversion... where
+ * should this really be?
+ */
+ if (event->type==MOUSEMOVE) {
+ /* Note, not nice! XXX 2.5 event hack */
+ val = event->x - ar->winrct.xmin;
+ mousedevice->ConvertBlenderEvent(MOUSEX, val);
+
+ val = ar->winy - (event->y - ar->winrct.ymin) - 1;
+ mousedevice->ConvertBlenderEvent(MOUSEY, val);
+ }
+ else {
+ mousedevice->ConvertBlenderEvent(event->type,event->val);
+ }
+
+ BLI_remlink(&win->queue, event);
+ wm_event_free(event);
+ }
+
+ if(win != CTX_wm_window(C)) {
+ exitrequested= KX_EXIT_REQUEST_OUTSIDE; /* window closed while bge runs */
+ }
+ return exitrequested;
+}
+
+struct BL_KetsjiNextFrameState {
+ struct KX_KetsjiEngine* ketsjiengine;
+ struct bContext *C;
+ struct wmWindow* win;
+ struct Scene* scene;
+ struct ARegion *ar;
+ KX_BlenderKeyboardDevice* keyboarddevice;
+ KX_BlenderMouseDevice* mousedevice;
+ int draw_letterbox;
+} ketsjinextframestate;
+
+int BL_KetsjiPyNextFrame(void *state0)
+{
+ BL_KetsjiNextFrameState *state = (BL_KetsjiNextFrameState *) state0;
+ return BL_KetsjiNextFrame(
+ state->ketsjiengine,
+ state->C,
+ state->win,
+ state->scene,
+ state->ar,
+ state->keyboarddevice,
+ state->mousedevice,
+ state->draw_letterbox);
+}
+
extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *cam_frame, int always_use_expand_framing)
{
/* context values */
@@ -346,6 +439,7 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *c
rasterizer->SetBackColor(scene->gm.framing.col[0], scene->gm.framing.col[1], scene->gm.framing.col[2], 0.0f);
}
+ char *python_main = NULL;
if (exitrequested != KX_EXIT_REQUEST_QUIT_GAME)
{
if (rv3d->persp != RV3D_CAMOB)
@@ -440,71 +534,47 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *c
// Could be in StartEngine set the framerate, we need the scene to do this
ketsjiengine->SetAnimFrameRate(FPS);
+ char *python_main = NULL;
+ pynextframestate.state = NULL;
+ pynextframestate.func = NULL;
+#ifdef WITH_PYTHON
+ python_main = KX_GetPythonMain(scene);
+#endif // WITH_PYTHON
// the mainloop
printf("\nBlender Game Engine Started\n");
- while (!exitrequested)
- {
- // first check if we want to exit
- exitrequested = ketsjiengine->GetExitCode();
-
- // kick the engine
- bool render = ketsjiengine->NextFrame();
-
- if (render)
- {
- if (draw_letterbox) {
- // Clear screen to border color
- // We do this here since we set the canvas to be within the frames. This means the engine
- // itself is unaware of the extra space, so we clear the whole region for it.
- glClearColor(scene->gm.framing.col[0], scene->gm.framing.col[1], scene->gm.framing.col[2], 1.0f);
- glViewport(ar->winrct.xmin, ar->winrct.ymin,
- BLI_RCT_SIZE_X(&ar->winrct), BLI_RCT_SIZE_Y(&ar->winrct));
- glClear(GL_COLOR_BUFFER_BIT);
- }
-
- // render the frame
- ketsjiengine->Render();
- }
-
- wm_window_process_events_nosleep();
-
- // test for the ESC key
- //XXX while (qtest())
- while(wmEvent *event= (wmEvent *)win->queue.first)
+ if (python_main) {
+ char *python_code = KX_GetPythonCode(blenderdata, python_main);
+ if (python_code) {
+#ifdef WITH_PYTHON
+ ketsjinextframestate.ketsjiengine = ketsjiengine;
+ ketsjinextframestate.C = C;
+ ketsjinextframestate.win = win;
+ ketsjinextframestate.scene = scene;
+ ketsjinextframestate.ar = ar;
+ ketsjinextframestate.keyboarddevice = keyboarddevice;
+ ketsjinextframestate.mousedevice = mousedevice;
+ ketsjinextframestate.draw_letterbox = draw_letterbox;
+
+ pynextframestate.state = &ketsjinextframestate;
+ pynextframestate.func = &BL_KetsjiPyNextFrame;
+ printf("Yielding control to Python script '%s'...\n", python_main);
+ PyRun_SimpleString(python_code);
+ printf("Exit Python script '%s'\n", python_main);
+#endif // WITH_PYTHON
+ MEM_freeN(python_code);
+ }
+ }
+ else {
+ while (!exitrequested)
{
- short val = 0;
- //unsigned short event = 0; //XXX extern_qread(&val);
-
- if (keyboarddevice->ConvertBlenderEvent(event->type,event->val))
- exitrequested = KX_EXIT_REQUEST_BLENDER_ESC;
-
- /* Coordinate conversion... where
- * should this really be?
- */
- if (event->type==MOUSEMOVE) {
- /* Note, not nice! XXX 2.5 event hack */
- val = event->x - ar->winrct.xmin;
- mousedevice->ConvertBlenderEvent(MOUSEX, val);
-
- val = ar->winy - (event->y - ar->winrct.ymin) - 1;
- mousedevice->ConvertBlenderEvent(MOUSEY, val);
- }
- else {
- mousedevice->ConvertBlenderEvent(event->type,event->val);
- }
-
- BLI_remlink(&win->queue, event);
- wm_event_free(event);
- }
-
- if (win != CTX_wm_window(C)) {
- exitrequested= KX_EXIT_REQUEST_OUTSIDE; /* window closed while bge runs */
+ exitrequested = BL_KetsjiNextFrame(ketsjiengine, C, win, scene, ar, keyboarddevice, mousedevice, draw_letterbox);
}
}
printf("Blender Game Engine Finished\n");
exitstring = ketsjiengine->GetExitString();
- gs = *(ketsjiengine->GetGlobalSettings());
+ if (python_main) MEM_freeN(python_main);
+ gs = *(ketsjiengine->GetGlobalSettings());
// when exiting the mainloop
#ifdef WITH_PYTHON
diff --git a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
index 41f641b4368..f4d4f774db2 100644
--- a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
+++ b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
@@ -47,6 +47,7 @@
#endif // __APPLE__
#include "KX_KetsjiEngine.h"
#include "KX_PythonInit.h"
+#include "KX_PythonMain.h"
/**********************************
* Begin Blender include block
@@ -332,6 +333,40 @@ static BlendFileData *load_game_data(const char *progname, char *filename = NULL
return bfd;
}
+bool GPG_NextFrame(GHOST_ISystem* system, GPG_Application *app, int &exitcode, STR_String &exitstring, GlobalSettings *gs)
+{
+ bool run = true;
+ system->processEvents(false);
+ system->dispatchEvents();
+ if ((exitcode = app->getExitRequested()))
+ {
+ run = false;
+ exitstring = app->getExitString();
+ *gs = *app->getGlobalSettings();
+ }
+ return run;
+}
+
+struct GPG_NextFrameState {
+ GHOST_ISystem* system;
+ GPG_Application *app;
+ GlobalSettings *gs;
+} gpg_nextframestate;
+
+int GPG_PyNextFrame(void *state0)
+{
+ GPG_NextFrameState *state = (GPG_NextFrameState *) state0;
+ int exitcode;
+ STR_String exitstring;
+ bool run = GPG_NextFrame(state->system, state->app, exitcode, exitstring, state->gs);
+ if (run) return 0;
+ else {
+ if (exitcode)
+ fprintf(stderr, "Exit code %d: %s\n", exitcode, exitstring.ReadPtr());
+ return 1;
+ }
+}
+
int main(int argc, char** argv)
{
int i;
@@ -966,17 +1001,39 @@ int main(int argc, char** argv)
// Enter main loop
bool run = true;
- while (run)
+ char *python_main = NULL;
+ pynextframestate.state = NULL;
+ pynextframestate.func = NULL;
+#ifdef WITH_PYTHON
+ python_main = KX_GetPythonMain(scene);
+#endif // WITH_PYTHON
+ if (python_main)
{
- system->processEvents(false);
- system->dispatchEvents();
- app.EngineNextFrame();
-
- if ((exitcode = app.getExitRequested()))
+ char *python_code = KX_GetPythonCode(maggie, python_main);
+ if (python_code)
+ {
+#ifdef WITH_PYTHON
+ gpg_nextframestate.system = system;
+ gpg_nextframestate.app = &app;
+ gpg_nextframestate.gs = &gs;
+ pynextframestate.state = &gpg_nextframestate;
+ pynextframestate.func = &GPG_PyNextFrame;
+
+ printf("Yielding control to Python script '%s'...\n", python_main);
+ PyRun_SimpleString(python_code);
+ printf("Exit Python script '%s'\n", python_main);
+#endif // WITH_PYTHON
+ MEM_freeN(python_code);
+ }
+ else {
+ fprintf(stderr, "ERROR: cannot yield control to Python: no Python text data block named '%s'\n", python_main);
+ }
+ }
+ else
+ {
+ while (run)
{
- run = false;
- exitstring = app.getExitString();
- gs = *app.getGlobalSettings();
+ run = GPG_NextFrame(system, &app, exitcode, exitstring, &gs);
}
}
app.StopGameEngine();
@@ -986,6 +1043,7 @@ int main(int argc, char** argv)
system->removeEventConsumer(&app);
BLO_blendfiledata_free(bfd);
+ if (python_main) MEM_freeN(python_main);
}
} while (exitcode == KX_EXIT_REQUEST_RESTART_GAME || exitcode == KX_EXIT_REQUEST_START_OTHER_GAME);
}
diff --git a/source/gameengine/Ketsji/CMakeLists.txt b/source/gameengine/Ketsji/CMakeLists.txt
index 4b3426e0784..269311b7e00 100644
--- a/source/gameengine/Ketsji/CMakeLists.txt
+++ b/source/gameengine/Ketsji/CMakeLists.txt
@@ -107,6 +107,7 @@ set(SRC
KX_PyMath.cpp
KX_PythonInit.cpp
KX_PythonInitTypes.cpp
+ KX_PythonMain.cpp
KX_PythonSeq.cpp
KX_RadarSensor.cpp
KX_RayCast.cpp
@@ -189,6 +190,7 @@ set(SRC
KX_PyMath.h
KX_PythonInit.h
KX_PythonInitTypes.h
+ KX_PythonMain.h
KX_PythonSeq.h
KX_RadarSensor.h
KX_RayCast.h
diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp
index 581b3712f97..86928803502 100644
--- a/source/gameengine/Ketsji/KX_PythonInit.cpp
+++ b/source/gameengine/Ketsji/KX_PythonInit.cpp
@@ -811,6 +811,23 @@ static PyObject *gLibList(PyObject*, PyObject* args)
return list;
}
+struct PyNextFrameState pynextframestate;
+static PyObject *gPyNextFrame(PyObject *)
+{
+ if (pynextframestate.func == NULL) Py_RETURN_NONE;
+ if (pynextframestate.state == NULL) Py_RETURN_NONE; //should never happen; raise exception instead?
+
+ if (pynextframestate.func(pynextframestate.state)) //nonzero = stop
+ {
+ Py_RETURN_TRUE;
+ }
+ else // 0 = go on
+ {
+ Py_RETURN_FALSE;
+ }
+}
+
+
static struct PyMethodDef game_methods[] = {
{"expandPath", (PyCFunction)gPyExpandPath, METH_VARARGS, (const char *)gPyExpandPath_doc},
{"startGame", (PyCFunction)gPyStartGame, METH_VARARGS, (const char *)gPyStartGame_doc},
@@ -840,7 +857,7 @@ static struct PyMethodDef game_methods[] = {
{"getBlendFileList", (PyCFunction)gPyGetBlendFileList, METH_VARARGS, (const char *)"Gets a list of blend files in the same directory as the current blend file"},
{"PrintGLInfo", (PyCFunction)pyPrintExt, METH_NOARGS, (const char *)"Prints GL Extension Info"},
{"PrintMemInfo", (PyCFunction)pyPrintStats, METH_NOARGS, (const char *)"Print engine statistics"},
-
+ {"NextFrame", (PyCFunction)gPyNextFrame, METH_NOARGS, (const char *)"Render next frame (if Python has control)"},
/* library functions */
{"LibLoad", (PyCFunction)gLibLoad, METH_VARARGS|METH_KEYWORDS, (const char *)""},
{"LibNew", (PyCFunction)gLibNew, METH_VARARGS, (const char *)""},
diff --git a/source/gameengine/Ketsji/KX_PythonInit.h b/source/gameengine/Ketsji/KX_PythonInit.h
index 866681b9da7..1500dd97ae1 100644
--- a/source/gameengine/Ketsji/KX_PythonInit.h
+++ b/source/gameengine/Ketsji/KX_PythonInit.h
@@ -70,6 +70,16 @@ class KX_Scene;
void KX_SetActiveScene(class KX_Scene* scene);
class KX_Scene* KX_GetActiveScene();
class KX_KetsjiEngine* KX_GetActiveEngine();
+
+typedef int (*PyNextFrameFunc)(void *);
+struct PyNextFrameState {
+ //state: can be either a GPG_NextFrameState or a BL_KetsjiNextFrameState
+ void *state;
+ //func: can be either GPG_PyNextFrame or BL_KetsjiPyNextFrame
+ PyNextFrameFunc func;
+};
+extern struct PyNextFrameState pynextframestate;
+
#include "MT_Vector3.h"
void KX_RasterizerDrawDebugLine(const MT_Vector3& from,const MT_Vector3& to,const MT_Vector3& color);
diff --git a/source/gameengine/Ketsji/KX_PythonMain.cpp b/source/gameengine/Ketsji/KX_PythonMain.cpp
new file mode 100644
index 00000000000..969ecbea5a9
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_PythonMain.cpp
@@ -0,0 +1,78 @@
+/*
+ * $Id: KX_PythonMain.cpp 37750 2011-06-27 09:27:56Z sjoerd $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+/** \file gameengine/Ketsji/KX_KetsjiPythonMain.cpp
+ * \ingroup ketsji
+ */
+
+#include "KX_PythonMain.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "RNA_access.h"
+#include "MEM_guardedalloc.h"
+#include "BKE_text.h"
+#include "BKE_main.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+extern "C" char *KX_GetPythonMain(struct Scene* scene)
+{
+ //examine custom scene properties
+
+ PointerRNA sceneptr;
+ RNA_id_pointer_create(&scene->id, &sceneptr);
+
+ PropertyRNA *pymain = RNA_struct_find_property(&sceneptr, "[\"__main__\"]");
+ if (pymain == NULL) return NULL;
+ char *python_main;
+ int len;
+ python_main = RNA_property_string_get_alloc(&sceneptr, pymain, NULL, 0, &len);
+ return python_main;
+}
+
+extern "C" char *KX_GetPythonCode(Main *main, char *python_main)
+{
+ PointerRNA mainptr, txtptr;
+ PropertyRNA *texts;
+
+ RNA_main_pointer_create(main, &mainptr);
+ texts = RNA_struct_find_property(&mainptr, "texts");
+ char *python_code = NULL;
+ int ok = RNA_property_collection_lookup_string(&mainptr, texts, python_main, &txtptr);
+ if (ok) {
+ Text *text = (Text *) txtptr.data;
+ python_code = txt_to_buf(text);
+ }
+ return python_code;
+}
+
diff --git a/source/gameengine/Ketsji/KX_PythonMain.h b/source/gameengine/Ketsji/KX_PythonMain.h
new file mode 100644
index 00000000000..1460ea2ca96
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_PythonMain.h
@@ -0,0 +1,41 @@
+/*
+ * $Id: KX_PythonMain.h 37750 2011-06-27 09:27:56Z sjoerd $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file KX_PythonMain.h
+ * \ingroup ketsji
+ */
+
+#ifndef __KX_PYTHON_MAIN
+#define __KX_PYTHON_MAIN
+
+#include "BKE_main.h"
+#include "DNA_scene_types.h"
+extern "C" char *KX_GetPythonMain(struct Scene* scene);
+extern "C" char *KX_GetPythonCode(struct Main *main, char *python_main);
+#endif