Skip to content
Browse files

Merge branch 'master' of https://github.com/adventuregamestudio/ags

  • Loading branch information...
2 parents e64c0ef + 9fc9417 commit f0842cd9ba19b2b7066a720204447a1c51584642 @tzachshabtay tzachshabtay committed Apr 4, 2013
View
19 Common/ac/gamesetupstructbase.cpp
@@ -52,9 +52,16 @@ void GameSetupStructBase::ReadFromFile(Stream *in)
//for (i = 0; i < MAXGLOBALMES; i++)
// messages[i] = (char*)in->ReadInt32();
+ // The following pointers are used as flags at one point
+ // during game loading, therefore they are initialized with
+ // some values here. These values are never treated as
+ // actual addresses, only as boolean values.
+ // See:
+ // - GameSetupStruct::read_words_dictionary(), dict
+ // - load_game_file(), compiled_script
dict = (WordsDictionary *) in->ReadInt32();
- globalscript = (char *) in->ReadInt32();
- chars = (CharacterInfo *) in->ReadInt32();
+ in->ReadInt32(); // globalscript
+ in->ReadInt32(); // chars
compiled_script = (ccScript *) in->ReadInt32();
}
@@ -87,8 +94,8 @@ void GameSetupStructBase::WriteToFile(Stream *out)
out->WriteArrayOfInt32(reserved, 17);
// write the final ptrs so we know to load dictionary, scripts etc
out->WriteArrayOfIntPtr32((intptr_t*)messages, MAXGLOBALMES);
- out->WriteInt32((int32)dict);
- out->WriteInt32((int32)globalscript);
- out->WriteInt32((int32)chars);
- out->WriteInt32((int32)compiled_script);
+ out->WriteInt32(dict ? 1 : 0);
+ out->WriteInt32(0); // globalscript
+ out->WriteInt32(0); // chars
+ out->WriteInt32(compiled_script ? 1 : 0);
}
View
7 Common/ac/gamesetupstructbase.h
@@ -64,6 +64,13 @@ struct GameSetupStructBase {
char *globalscript;
CharacterInfo *chars;
ccScript *compiled_script;
+ // [IKM] 2013-03-30
+ // NOTE: it looks like nor 'globalscript', not 'compiled_script' are used
+ // to store actual script data anytime; 'ccScript* gamescript' global
+ // pointer is used for that instead.
+ // 'compiled_script' member is used once as a flag, to indicate that there's
+ // a global script data to be loaded; 'globalscript' is not used anywhere
+ // for anything useful.
void ReadFromFile(Common::Stream *in);
void WriteToFile(Common::Stream *out);
View
7 Editor/AGS.Editor/Panes/WelcomePane.Designer.cs
@@ -144,7 +144,7 @@ private void InitializeComponent()
this.lnkUpgradingFrom302.TabIndex = 4;
this.lnkUpgradingFrom302.TabStop = true;
this.lnkUpgradingFrom302.Text = "If you were using AGS 3.1.2, read this page which tells you the main breaking cha" +
- "nges in AGS 3.3.";
+ "nges in AGS 3.2.";
this.lnkUpgradingFrom302.UseCompatibleTextRendering = true;
this.lnkUpgradingFrom302.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.lnkUpgradingFrom302_LinkClicked);
//
@@ -166,8 +166,9 @@ private void InitializeComponent()
this.lblUpgradingInfo.Name = "lblUpgradingInfo";
this.lblUpgradingInfo.Size = new System.Drawing.Size(292, 28);
this.lblUpgradingInfo.TabIndex = 2;
- this.lblUpgradingInfo.Text = "As usual, this latest version of AGS brings you more goodies than you can shake a" +
- " stick at!";
+ // TODO: replace this line with something more generic for the next version; this one is for 3.3 only
+ this.lblUpgradingInfo.Text = "This is the first version of AGS ever released as the collaborative work of" +
+ " community members and fellow contributors.";
//
// lnkUpgrading
//
View
2 Editor/AGS.Editor/Panes/WelcomePane.resx
@@ -124,6 +124,8 @@
* Find where your characters, dialogs, views, inventory items and global variables are used using a simple menu click
* Easy navigation from an open document to its location in the tree using a simple menu click
* New shortcuts in the script editor to navigate to a specific line (Ctrl+G) and switch between header and script (Ctrl+M)
+* The engine runs games made with previous versions of AGS as old as 2.5
+* Run games with x5, x6 ,x7 or x8 graphics scaling filter
* And loads more!</value>
</data>
</root>
View
BIN Editor/AGS.Editor/Resources/splash.bmp
Binary file not shown.
View
2 Engine/Makefile-defs.linux
@@ -1,6 +1,6 @@
INCDIR = ../Engine ../Common ../Common/libinclude ../Plugins
LIBDIR =
-override CFLAGS += -O2 -pie -fpie -g -fsigned-char -Wfatal-errors -DNDEBUG -DAGS_RUNTIME_PATCH_ALLEGRO -DAGS_HAS_CD_AUDIO -DAGS_CASE_SENSITIVE_FILESYSTEM -DALLEGRO_STATICLINK -DLINUX_VERSION -DDISABLE_MPEG_AUDIO -DBUILTIN_PLUGINS -DRTLD_NEXT $(shell pkg-config --cflags freetype2)
+override CFLAGS += -O2 -g -fsigned-char -Wfatal-errors -DNDEBUG -DAGS_RUNTIME_PATCH_ALLEGRO -DAGS_HAS_CD_AUDIO -DAGS_CASE_SENSITIVE_FILESYSTEM -DALLEGRO_STATICLINK -DLINUX_VERSION -DDISABLE_MPEG_AUDIO -DBUILTIN_PLUGINS -DRTLD_NEXT $(shell pkg-config --cflags freetype2)
override CXXFLAGS += -fno-rtti -Wno-write-strings -fpermissive
LIBS = -rdynamic $(shell allegro-config --libs) -laldmb -ldumb -Wl,-Bdynamic -ltheora -logg
View
15 Engine/ac/dynobj/cc_dynamicobject.cpp
@@ -45,8 +45,8 @@ void ccSetStringClassImpl(ICCStringClass *theClass) {
// register a memory handle for the object and allow script
// pointers to point to it
-int32_t ccRegisterManagedObject(const void *object, ICCDynamicObject *callback) {
- int32_t handl = pool.AddObject((const char*)object, callback);
+int32_t ccRegisterManagedObject(const void *object, ICCDynamicObject *callback, bool plugin_object) {
+ int32_t handl = pool.AddObject((const char*)object, callback, plugin_object);
#ifdef DEBUG_MANAGED_OBJECTS
char bufff[200];
@@ -58,8 +58,8 @@ int32_t ccRegisterManagedObject(const void *object, ICCDynamicObject *callback)
}
// register a de-serialized object
-int32_t ccRegisterUnserializedObject(int index, const void *object, ICCDynamicObject *callback) {
- return pool.AddObject((const char*)object, callback, index);
+int32_t ccRegisterUnserializedObject(int index, const void *object, ICCDynamicObject *callback, bool plugin_object) {
+ return pool.AddObject((const char*)object, callback, plugin_object, index);
}
// unregister a particular object
@@ -130,17 +130,18 @@ const char *ccGetObjectAddressFromHandle(int32_t handle) {
return addr;
}
-void ccGetObjectAddressAndManagerFromHandle(int32_t handle, void *&object, ICCDynamicObject *&manager)
+ScriptValueType ccGetObjectAddressAndManagerFromHandle(int32_t handle, void *&object, ICCDynamicObject *&manager)
{
if (handle == 0) {
object = NULL;
manager = NULL;
- return;
+ return kScValUndefined;
}
- pool.HandleToAddressAndManager(handle, object, manager);
+ ScriptValueType obj_type = pool.HandleToAddressAndManager(handle, object, manager);
if (object == NULL) {
cc_error("Error retrieving pointer: invalid handle %d", handle);
}
+ return obj_type;
}
int ccAddObjectReference(int32_t handle) {
View
7 Engine/ac/dynobj/cc_dynamicobject.h
@@ -20,6 +20,7 @@
#define __CC_DYNAMICOBJECT_H
#include "util/file.h"
+#include "script/runtimescriptvalue.h"
// Forward declaration
namespace AGS { namespace Common { class Stream; } }
@@ -63,9 +64,9 @@ struct ICCStringClass {
extern void ccSetStringClassImpl(ICCStringClass *theClass);
// register a memory handle for the object and allow script
// pointers to point to it
-extern int32_t ccRegisterManagedObject(const void *object, ICCDynamicObject *);
+extern int32_t ccRegisterManagedObject(const void *object, ICCDynamicObject *, bool plugin_object = false);
// register a de-serialized object
-extern int32_t ccRegisterUnserializedObject(int index, const void *object, ICCDynamicObject *);
+extern int32_t ccRegisterUnserializedObject(int index, const void *object, ICCDynamicObject *, bool plugin_object = false);
// unregister a particular object
extern int ccUnRegisterManagedObject(const void *object);
// remove all registered objects
@@ -79,7 +80,7 @@ extern void ccAttemptDisposeObject(int32_t handle);
// translate between object handles and memory addresses
extern int32_t ccGetObjectHandleFromAddress(const char *address);
extern const char *ccGetObjectAddressFromHandle(int32_t handle);
-extern void ccGetObjectAddressAndManagerFromHandle(int32_t handle, void *&object, ICCDynamicObject *&manager);
+extern ScriptValueType ccGetObjectAddressAndManagerFromHandle(int32_t handle, void *&object, ICCDynamicObject *&manager);
extern int ccAddObjectReference(int32_t handle);
extern int ccReleaseObjectReference(int32_t handle);
View
19 Engine/ac/dynobj/managedobjectpool.cpp
@@ -23,7 +23,9 @@
using AGS::Common::Stream;
-void ManagedObjectPool::ManagedObject::init(int32_t theHandle, const char *theAddress, ICCDynamicObject *theCallback) {
+void ManagedObjectPool::ManagedObject::init(int32_t theHandle, const char *theAddress,
+ ICCDynamicObject *theCallback, ScriptValueType objType) {
+ obj_type = objType;
handle = theHandle;
addr = theAddress;
callback = theCallback;
@@ -137,16 +139,17 @@ const char* ManagedObjectPool::HandleToAddress(int32_t handle) {
return objects[handle].addr;
}
-void ManagedObjectPool::HandleToAddressAndManager(int32_t handle, void *&object, ICCDynamicObject *&manager) {
+ScriptValueType ManagedObjectPool::HandleToAddressAndManager(int32_t handle, void *&object, ICCDynamicObject *&manager) {
object = NULL;
manager = NULL;
// this function is called often (whenever a pointer is used)
if ((handle < 1) || (handle >= arrayAllocLimit))
- return;
+ return kScValUndefined;
if (objects[handle].handle == 0)
- return;
+ return kScValUndefined;
object = (void*)objects[handle].addr;
manager = objects[handle].callback;
+ return objects[handle].obj_type;
}
int ManagedObjectPool::RemoveObject(const char *address) {
@@ -180,15 +183,15 @@ void ManagedObjectPool::RunGarbageCollection()
}
}
-int ManagedObjectPool::AddObject(const char *address, ICCDynamicObject *callback, int useSlot) {
+int ManagedObjectPool::AddObject(const char *address, ICCDynamicObject *callback, bool plugin_object, int useSlot) {
if (useSlot == -1)
useSlot = numObjects;
objectCreationCounter++;
if (useSlot < arrayAllocLimit) {
// still space in the array, so use it
- objects[useSlot].init(useSlot, address, callback);
+ objects[useSlot].init(useSlot, address, callback, plugin_object ? kScValPluginObject : kScValDynamicObject);
if (useSlot == numObjects)
numObjects++;
return useSlot;
@@ -201,7 +204,7 @@ int ManagedObjectPool::AddObject(const char *address, ICCDynamicObject *callback
// long
for (int i = arrayAllocLimit - 1; i >= 1; i--) {
if (objects[i].handle == 0) {
- objects[i].init(i, address, callback);
+ objects[i].init(i, address, callback, plugin_object ? kScValPluginObject : kScValDynamicObject);
return i;
}
}
@@ -212,7 +215,7 @@ int ManagedObjectPool::AddObject(const char *address, ICCDynamicObject *callback
objects = (ManagedObject*)realloc(objects, sizeof(ManagedObject) * arrayAllocLimit);
memset(&objects[useSlot], 0, sizeof(ManagedObject) * ARRAY_INCREMENT_SIZE);
- objects[useSlot].init(useSlot, address, callback);
+ objects[useSlot].init(useSlot, address, callback, plugin_object ? kScValPluginObject : kScValDynamicObject);
if (useSlot == numObjects)
numObjects++;
return useSlot;
View
8 Engine/ac/dynobj/managedobjectpool.h
@@ -27,12 +27,14 @@ const int GARBAGE_COLLECTION_INTERVAL = 100;
struct ManagedObjectPool {
struct ManagedObject {
+ ScriptValueType obj_type;
int32_t handle;
const char *addr;
ICCDynamicObject * callback;
int refCount;
- void init(int32_t theHandle, const char *theAddress, ICCDynamicObject *theCallback);
+ void init(int32_t theHandle, const char *theAddress,
+ ICCDynamicObject *theCallback, ScriptValueType objType);
int remove(bool force);
int AddRef();
int CheckDispose();
@@ -53,11 +55,11 @@ struct ManagedObjectPool {
int32_t SubRef(int32_t handle);
int32_t AddressToHandle(const char *addr);
const char* HandleToAddress(int32_t handle);
- void HandleToAddressAndManager(int32_t handle, void *&object, ICCDynamicObject *&manager);
+ ScriptValueType HandleToAddressAndManager(int32_t handle, void *&object, ICCDynamicObject *&manager);
int RemoveObject(const char *address);
void RunGarbageCollectionIfAppropriate();
void RunGarbageCollection();
- int AddObject(const char *address, ICCDynamicObject *callback, int useSlot = -1);
+ int AddObject(const char *address, ICCDynamicObject *callback, bool plugin_object, int useSlot = -1);
void WriteToDisk(Common::Stream *out);
int ReadFromDisk(Common::Stream *in, ICCObjectReader *reader);
void reset();
View
6 Engine/ac/game.cpp
@@ -1157,10 +1157,10 @@ void save_game_room_state(Stream *out)
out->Write(&roomstat->tsdata[0], roomstat->tsdatasize);
}
else
- out->WriteInt8 (0); // <--- [IKM] added by me, CHECKME if needed / works correctly
+ out->WriteInt8(0);
}
else
- out->WriteInt8 (0);
+ out->WriteInt8(0);
}
}
@@ -1308,7 +1308,6 @@ void save_game_displayed_room_status(Stream *out)
// save the current troom, in case they save in room 600 or whatever
WriteRoomStatus_Aligned(&troom, out);
- //out->WriteArray(&troom,sizeof(RoomStatus),1);
if (troom.tsdatasize>0)
out->Write(&troom.tsdata[0],troom.tsdatasize);
@@ -1991,7 +1990,6 @@ void restore_game_displayed_room_status(Stream *in, Bitmap **newbscene)
}
else
troom.tsdata = NULL;
-
}
}
View
8 Engine/ac/gamestate.cpp
@@ -200,8 +200,8 @@ void GameState::ReadFromFile_v321(Stream *in)
gamma_adjustment = in->ReadInt32();
temporarily_turned_off_character = in->ReadInt16();
inv_backwards_compatibility = in->ReadInt16();
- gui_draw_order = (int*)in->ReadInt32();
- do_once_tokens = (char**)in->ReadInt32();
+ in->ReadInt32(); // gui_draw_order
+ in->ReadInt32(); // do_once_tokens;
num_do_once_tokens = in->ReadInt32();
text_min_display_time_ms = in->ReadInt32();
ignore_user_input_after_text_timeout_ms = in->ReadInt32();
@@ -376,8 +376,8 @@ void GameState::WriteToFile_v321(Stream *out)
out->WriteInt32( gamma_adjustment);
out->WriteInt16(temporarily_turned_off_character);
out->WriteInt16(inv_backwards_compatibility);
- out->WriteInt32((int32)gui_draw_order);
- out->WriteInt32((int32)do_once_tokens);
+ out->WriteInt32(0); // gui_draw_order
+ out->WriteInt32(0); // do_once_tokens
out->WriteInt32( num_do_once_tokens);
out->WriteInt32( text_min_display_time_ms);
out->WriteInt32( ignore_user_input_after_text_timeout_ms);
View
4 Engine/ac/roomstatus.cpp
@@ -28,7 +28,7 @@ void RoomStatus::ReadFromFile_v321(Stream *in)
ReadRoomObjects_Aligned(in);
in->ReadArrayOfInt16(flagstates, MAX_FLAGS);
tsdatasize = in->ReadInt32();
- tsdata = (char *) in->ReadInt32();
+ in->ReadInt32(); // tsdata
for (int i = 0; i < MAX_HOTSPOTS; ++i)
{
intrHotspot[i].ReadFromFile(in);
@@ -55,7 +55,7 @@ void RoomStatus::WriteToFile_v321(Stream *out)
WriteRoomObjects_Aligned(out);
out->WriteArrayOfInt16(flagstates, MAX_FLAGS);
out->WriteInt32(tsdatasize);
- out->WriteInt32((int)tsdata);
+ out->WriteInt32(0); // tsdata
for (int i = 0; i < MAX_HOTSPOTS; ++i)
{
intrHotspot[i].WriteToFile(out);
View
4 Engine/media/audio/queuedaudioitem.cpp
@@ -26,13 +26,13 @@ void QueuedAudioItem::ReadFromFile(Stream *in)
audioClipIndex = in->ReadInt16();
priority = in->ReadInt16();
repeat = in->ReadBool();
- cachedClip = (SOUNDCLIP*)in->ReadInt32();
+ in->ReadInt32(); // cachedClip
}
void QueuedAudioItem::WriteToFile(Stream *out)
{
out->WriteInt16(audioClipIndex);
out->WriteInt16(priority);
out->WriteBool(repeat);
- out->WriteInt32((int32)cachedClip);
+ out->WriteInt32(0); // cachedClip
}
View
26 Engine/media/video/video.cpp
@@ -28,9 +28,10 @@
#include "platform/base/agsplatformdriver.h"
#include "gfx/ddb.h"
#include "gfx/graphicsdriver.h"
-#include "gfx/bitmap.h"
+#include "gfx/allegrobitmap.h"
using AGS::Common::Bitmap;
+using AGS::Common::AllegroBitmap;
namespace BitmapHelper = AGS::Common::BitmapHelper;
@@ -98,54 +99,51 @@ extern "C" int fli_callback() {
// FLIC player end
// TODO: find a way to take Bitmap here?
-int theora_playing_callback(BITMAP *theoraBuffer_raw)
+AllegroBitmap theora_frame_wrapper;
+int theora_playing_callback(BITMAP *theoraBuffer)
{
- // [IKM] CHECKME later (need optimization / reimplementation)
- // This is probably not a very good thing to do in a video callback...
- // Good thing is that AllegroBitmap does not store much data on its own
- Bitmap *theoraBuffer = BitmapHelper::CreateRawObjectWrapper(theoraBuffer_raw);
-
if (theoraBuffer == NULL)
{
// No video, only sound
return check_if_user_input_should_cancel_video();
}
+ theora_frame_wrapper.WrapBitmapObject(theoraBuffer);
+
int drawAtX = 0, drawAtY = 0;
if (fli_ddb == NULL)
{
- fli_ddb = gfxDriver->CreateDDBFromBitmap(theoraBuffer, false, true);
+ fli_ddb = gfxDriver->CreateDDBFromBitmap(&theora_frame_wrapper, false, true);
}
if (stretch_flc)
{
drawAtX = scrnwid / 2 - fliTargetWidth / 2;
drawAtY = scrnhit / 2 - fliTargetHeight / 2;
if (!gfxDriver->HasAcceleratedStretchAndFlip())
{
- fli_target->StretchBlt(theoraBuffer, RectWH(0, 0, theoraBuffer->GetWidth(), theoraBuffer->GetHeight()),
+ fli_target->StretchBlt(&theora_frame_wrapper, RectWH(0, 0, theora_frame_wrapper.GetWidth(), theora_frame_wrapper.GetHeight()),
RectWH(drawAtX, drawAtY, fliTargetWidth, fliTargetHeight));
gfxDriver->UpdateDDBFromBitmap(fli_ddb, fli_target, false);
drawAtX = 0;
drawAtY = 0;
}
else
{
- gfxDriver->UpdateDDBFromBitmap(fli_ddb, theoraBuffer, false);
+ gfxDriver->UpdateDDBFromBitmap(fli_ddb, &theora_frame_wrapper, false);
fli_ddb->SetStretch(fliTargetWidth, fliTargetHeight);
}
}
else
{
- gfxDriver->UpdateDDBFromBitmap(fli_ddb, theoraBuffer, false);
- drawAtX = scrnwid / 2 - theoraBuffer->GetWidth() / 2;
- drawAtY = scrnhit / 2 - theoraBuffer->GetHeight() / 2;
+ gfxDriver->UpdateDDBFromBitmap(fli_ddb, &theora_frame_wrapper, false);
+ drawAtX = scrnwid / 2 - theora_frame_wrapper.GetWidth() / 2;
+ drawAtY = scrnhit / 2 - theora_frame_wrapper.GetHeight() / 2;
}
gfxDriver->DrawSprite(drawAtX, drawAtY, fli_ddb);
render_to_screen(virtual_screen, 0, 0);
update_polled_stuff_and_crossfade ();
- delete theoraBuffer;
return check_if_user_input_should_cancel_video();
}
View
28 Engine/plugin/agsplugin.cpp
@@ -602,9 +602,9 @@ int IAGSEngine::CallGameScriptFunction(const char *name, int32 globalScript, int
toRun = roominst;
RuntimeScriptValue params[3];
- params[0].SetInt32(arg1);
- params[1].SetInt32(arg2);
- params[2].SetInt32(arg3);
+ params[0].SetPluginArgument(arg1);
+ params[1].SetPluginArgument(arg2);
+ params[2].SetPluginArgument(arg3);
int toret = toRun->RunScriptFunctionIfExists((char*)name, numArgs, params);
return toret;
}
@@ -676,12 +676,12 @@ void IAGSEngine::QueueGameScriptFunction(const char *name, int32 globalScript, i
}
strcat(scNameToRun, name);
- curscript->run_another(scNameToRun, RuntimeScriptValue().SetInt32(arg1), RuntimeScriptValue().SetInt32(arg2));
+ curscript->run_another(scNameToRun, RuntimeScriptValue().SetPluginArgument(arg1), RuntimeScriptValue().SetPluginArgument(arg2));
}
int IAGSEngine::RegisterManagedObject(const void *object, IAGSScriptManagedObject *callback) {
- GlobalReturnValue.SetDynamicObject((void*)object, (ICCDynamicObject*)callback);
- return ccRegisterManagedObject(object, (ICCDynamicObject*)callback);
+ GlobalReturnValue.SetPluginObject((void*)object, (ICCDynamicObject*)callback);
+ return ccRegisterManagedObject(object, (ICCDynamicObject*)callback, true);
}
void IAGSEngine::AddManagedObjectReader(const char *typeName, IAGSManagedObjectReader *reader) {
@@ -702,8 +702,8 @@ void IAGSEngine::AddManagedObjectReader(const char *typeName, IAGSManagedObjectR
}
void IAGSEngine::RegisterUnserializedObject(int key, const void *object, IAGSScriptManagedObject *callback) {
- GlobalReturnValue.SetDynamicObject((void*)object, (ICCDynamicObject*)callback);
- ccRegisterUnserializedObject(key, object, (ICCDynamicObject*)callback);
+ GlobalReturnValue.SetPluginObject((void*)object, (ICCDynamicObject*)callback);
+ ccRegisterUnserializedObject(key, object, (ICCDynamicObject*)callback, true);
}
int IAGSEngine::GetManagedObjectKeyByAddress(const char *address) {
@@ -713,13 +713,21 @@ int IAGSEngine::GetManagedObjectKeyByAddress(const char *address) {
void* IAGSEngine::GetManagedObjectAddressByKey(int key) {
void *object;
ICCDynamicObject *manager;
- ccGetObjectAddressAndManagerFromHandle(key, object, manager);
- GlobalReturnValue.SetDynamicObject(object, manager);
+ ScriptValueType obj_type = ccGetObjectAddressAndManagerFromHandle(key, object, manager);
+ if (obj_type == kScValPluginObject)
+ {
+ GlobalReturnValue.SetPluginObject(object, manager);
+ }
+ else
+ {
+ GlobalReturnValue.SetDynamicObject(object, manager);
+ }
return object;
}
const char* IAGSEngine::CreateScriptString(const char *fromText) {
const char *string = CreateNewScriptString(fromText);
+ // Should be still standard dynamic object, because not managed by plugin
GlobalReturnValue.SetDynamicObject((void*)string, &myScriptStringImpl);
return string;
}
View
74 Engine/script/cc_instance.cpp
@@ -826,8 +826,7 @@ int ccInstance::Run(int32_t curpc)
pc += (reg1.IValue - thisbase[curnest]);
}
- if (next_call_needs_object) // is this right?
- next_call_needs_object = 0;
+ next_call_needs_object = 0;
if (loopIterationCheckDisabled)
loopIterationCheckDisabled++;
@@ -935,8 +934,15 @@ int ccInstance::Run(int32_t curpc)
int32_t handle = registers[SREG_MAR].ReadInt32();
void *object;
ICCDynamicObject *manager;
- ccGetObjectAddressAndManagerFromHandle(handle, object, manager);
- reg1.SetDynamicObject( object, manager );
+ ScriptValueType obj_type = ccGetObjectAddressAndManagerFromHandle(handle, object, manager);
+ if (obj_type == kScValPluginObject)
+ {
+ reg1.SetPluginObject( object, manager );
+ }
+ else
+ {
+ reg1.SetDynamicObject( object, manager );
+ }
// if error occurred, cc_error will have been set
if (ccError)
@@ -951,10 +957,15 @@ int ccInstance::Run(int32_t curpc)
{
address = (char*)reg1.StcArr->GetElementPtr(reg1.Ptr, reg1.IValue);
}
- else if (reg1.Type == kScValDynamicObject)
+ else if (reg1.Type == kScValDynamicObject ||
+ reg1.Type == kScValPluginObject)
{
address = reg1.Ptr;
}
+ else if (reg1.Type == kScValPluginArg)
+ {
+ address = (char*)reg1.IValue;
+ }
// There's one possible case when the reg1 is 0, which means writing nullptr
else if (!reg1.IsNull())
{
@@ -980,10 +991,15 @@ int ccInstance::Run(int32_t curpc)
{
address = (char*)reg1.StcArr->GetElementPtr(reg1.Ptr, reg1.IValue);
}
- else if (reg1.Type == kScValDynamicObject)
+ else if (reg1.Type == kScValDynamicObject ||
+ reg1.Type == kScValPluginObject)
{
address = reg1.Ptr;
}
+ else if (reg1.Type == kScValPluginArg)
+ {
+ address = (char*)reg1.IValue;
+ }
// There's one possible case when the reg1 is 0, which means writing nullptr
else if (!reg1.IsNull())
{
@@ -1084,8 +1100,7 @@ int ccInstance::Run(int32_t curpc)
return -1;
}
- if (next_call_needs_object)
- next_call_needs_object = 0;
+ next_call_needs_object = 0;
pc = oldpc;
was_just_callas = func_callstack.Count;
@@ -1110,10 +1125,33 @@ int ccInstance::Run(int32_t curpc)
RuntimeScriptValue return_value;
- if (next_call_needs_object)
+ if (reg1.Type == kScValPluginFunction)
+ {
+ GlobalReturnValue.Invalidate();
+ int32_t int_ret_val;
+ if (next_call_needs_object)
+ {
+ RuntimeScriptValue obj_rval = registers[SREG_OP];
+ obj_rval.DirectPtr();
+ int_ret_val = call_function((intptr_t)reg1.Ptr, &obj_rval, num_args_to_func, func_callstack.GetHead() + 1);
+ }
+ else
+ {
+ int_ret_val = call_function((intptr_t)reg1.Ptr, NULL, num_args_to_func, func_callstack.GetHead() + 1);
+ }
+
+ if (GlobalReturnValue.IsValid())
+ {
+ return_value = GlobalReturnValue;
+ }
+ else
+ {
+ return_value.SetPluginArgument(int_ret_val);
+ }
+ }
+ else if (next_call_needs_object)
{
// member function call
- next_call_needs_object = 0;
if (reg1.Type == kScValObjectFunction)
{
RuntimeScriptValue obj_rval = registers[SREG_OP];
@@ -1129,19 +1167,6 @@ int ccInstance::Run(int32_t curpc)
{
return_value = reg1.SPfn(func_callstack.GetHead() + 1, num_args_to_func);
}
- else if (reg1.Type == kScValPluginFunction)
- {
- GlobalReturnValue.Invalidate();
- int32_t int_ret_val = call_function((intptr_t)reg1.Ptr, num_args_to_func, func_callstack.GetHead() + 1);
- if (GlobalReturnValue.IsValid())
- {
- return_value = GlobalReturnValue;
- }
- else
- {
- return_value.SetInt32(int_ret_val);
- }
- }
else if (reg1.Type == kScValObjectFunction)
{
cc_error("unexpected object function pointer on SCMD_CALLEXT");
@@ -1158,6 +1183,7 @@ int ccInstance::Run(int32_t curpc)
registers[SREG_AX] = return_value;
current_instance = this;
+ next_call_needs_object = 0;
num_args_to_func = -1;
break;
}
@@ -1179,7 +1205,7 @@ int ccInstance::Run(int32_t curpc)
cc_error("!Null pointer referenced");
return -1;
}
- if (reg1.Type == kScValDynamicObject ||
+ if (reg1.Type == kScValDynamicObject || reg1.Type == kScValPluginObject ||
// This might be an object of USER-DEFINED type, calling its MEMBER-FUNCTION.
// Note, that this is the only case known when such object is written into reg[SREG_OP];
// in any other case that would count as error.
View
22 Engine/script/runtimescriptvalue.h
@@ -29,6 +29,8 @@ enum ScriptValueType
kScValUndefined, // to detect errors
kScValInteger, // as strictly 32-bit integer (for integer math)
kScValFloat, // as float (for floating point math), 32-bit
+ kScValPluginArg, // an 32-bit value, passed to a script function when called
+ // directly by plugin; is allowed to represent object pointer
kScValStackPtr, // as a pointer to stack entry
kScValData, // as a container for randomly sized data (usually array)
kScValGlobalVar, // as a pointer to script variable; used only for global vars,
@@ -38,6 +40,8 @@ enum ScriptValueType
kScValStaticObject, // as a pointer to static global script object
kScValStaticArray, // as a pointer to static global array (of static or dynamic objects)
kScValDynamicObject,// as a pointer to managed script object
+ kScValPluginObject, // as a pointer to object managed by plugin (similar to
+ // kScValDynamicObject, but has backward-compatible limitations)
kScValStaticFunction,// as a pointer to static function
kScValPluginFunction,// temporary workaround for plugins (unsafe function ptr)
kScValObjectFunction,// as a pointer to object member function, gets object pointer as
@@ -163,6 +167,15 @@ struct RuntimeScriptValue
{
return SetFloat(val ? 1.0F : 0.0F);
}
+ inline RuntimeScriptValue &SetPluginArgument(int32_t val)
+ {
+ Type = kScValPluginArg;
+ IValue = val;
+ Ptr = NULL;
+ MgrPtr = NULL;
+ Size = 4;
+ return *this;
+ }
inline RuntimeScriptValue &SetStackPtr(RuntimeScriptValue *stack_entry)
{
Type = kScValStackPtr;
@@ -227,6 +240,15 @@ struct RuntimeScriptValue
Size = 4;
return *this;
}
+ inline RuntimeScriptValue &SetPluginObject(void *object, ICCDynamicObject *manager)
+ {
+ Type = kScValPluginObject;
+ IValue = 0;
+ Ptr = (char*)object;
+ DynMgr = manager;
+ Size = 4;
+ return *this;
+ }
inline RuntimeScriptValue &SetStaticFunction(ScriptAPIFunction *pfn)
{
Type = kScValStaticFunction;
View
17 Engine/script/script_runtime.cpp
@@ -141,7 +141,7 @@ void ccSetDebugHook(new_line_hook_type jibble)
new_line_hook = jibble;
}
-int call_function(intptr_t addr, int numparm, const RuntimeScriptValue *parms)
+int call_function(intptr_t addr, const RuntimeScriptValue *object, int numparm, const RuntimeScriptValue *parms)
{
if (!addr)
{
@@ -155,17 +155,24 @@ int call_function(intptr_t addr, int numparm, const RuntimeScriptValue *parms)
}
intptr_t parm_value[9];
- for (int i = 0; i < numparm; ++i)
+ if (object)
{
- switch (parms[i].Type)
+ parm_value[0] = (intptr_t)object->GetPtrWithOffset();
+ numparm++;
+ }
+
+ for (int ival = object ? 1 : 0, iparm = 0; ival < numparm; ++ival, ++iparm)
+ {
+ switch (parms[iparm].Type)
{
case kScValInteger:
case kScValFloat: // AGS passes floats, copying their values into long variable
- parm_value[i] = (intptr_t)parms[i].IValue;
+ case kScValPluginArg:
+ parm_value[ival] = (intptr_t)parms[iparm].IValue;
break;
break;
default:
- parm_value[i] = (intptr_t)parms[i].GetPtrWithOffset();
+ parm_value[ival] = (intptr_t)parms[iparm].GetPtrWithOffset();
break;
}
}
View
2 Engine/script/script_runtime.h
@@ -68,5 +68,5 @@ extern void ccSetScriptAliveTimer (int);
// reset the current while loop counter
extern void ccNotifyScriptStillAlive ();
// for calling exported plugin functions old-style
-extern int call_function(intptr_t addr, int numparm, const RuntimeScriptValue *parms);
+extern int call_function(intptr_t addr, const RuntimeScriptValue *object, int numparm, const RuntimeScriptValue *parms);
extern void nullfree(void *data); // in script/script_runtime

0 comments on commit f0842cd

Please sign in to comment.
Something went wrong with that request. Please try again.