Index: Daodan/src/BFW_ScriptingLanguage.h
===================================================================
--- Daodan/src/BFW_ScriptingLanguage.h	(revision 439)
+++ Daodan/src/BFW_ScriptingLanguage.h	(revision 439)
@@ -0,0 +1,38 @@
+#pragma once
+#ifndef BFW_UTILITY_H
+#define BFW_UTILITY_H
+
+#include "Daodan.h"
+
+#include <stdint.h>
+#include <stdbool.h>
+
+typedef enum {
+	sl_int32,
+	sl_str32, /* it's fixed length, 32 bytes. */
+	sl_float,
+	sl_bool,  /* Actually int32 0 or 1. */
+	sl_void,
+} sl_type;
+
+typedef struct {
+	sl_type type;
+	union {
+		void*    value;
+		uint32_t value_int32;
+		char*    value_str32;
+		float    value_float;
+		bool     value_bool;
+	};
+} sl_arg;
+
+typedef uint16_t (ONICALL *sl_func)(void* dontuse0, uint32_t numargs, sl_arg args[], void* dontuse1, void* dontuse2, sl_arg* ret);
+
+uint16_t ONICALL SLrScript_Command_Register_ReturnType(char* name, char* desc, char* argfmt, sl_type type, sl_func callback);
+uint16_t ONICALL SLrScript_Command_Register_Void(char* name, char* desc, char* argfmt, sl_func callback);
+uint16_t ONICALL SLrGlobalVariable_Register_Int32(char* name, char* desc, uint32_t* data);
+uint16_t ONICALL SLrGlobalVariable_Register_Float(char* name, char* desc, float* data);
+uint16_t ONICALL SLrGlobalVariable_Register_Bool(char* name, char* desc, uint32_t* data);
+uint16_t ONICALL SLrGlobalVariable_Register_String(char* name, char* desc, char* data);
+
+#endif
Index: Daodan/src/Daodan.c
===================================================================
--- Daodan/src/Daodan.c	(revision 438)
+++ Daodan/src/Daodan.c	(revision 439)
@@ -7,4 +7,5 @@
 #include "Daodan_Cheater.h"
 #include "Daodan_Persistence.h"
+#include "Daodan_BSL.h"
 
 #include "Daodan_WindowHack.h"
@@ -45,4 +46,7 @@
 bool patch_usedaodangl = false;
 bool patch_windowhack = true;
+bool patch_daodaninit = true;
+
+bool opt_usedaodanbsl = true;
 
 bool DDrPatch_Init()
@@ -165,5 +169,5 @@
 }
 
-enum {s_unknown, s_patch, s_language} ini_section;
+enum {s_unknown, s_options, s_patch, s_language} ini_section;
 
 bool DDrIniCallback(char* section, bool newsection, char* name, char* value)
@@ -171,5 +175,7 @@
 	if (newsection)
 	{
-		if (!stricmp(section, "patch"))
+		if (!stricmp(section, "options"))
+			ini_section = s_options;
+		else if (!stricmp(section, "patch"))
 			ini_section = s_patch;
 		else if (!stricmp(section, "language"))
@@ -184,4 +190,8 @@
 	switch (ini_section)
 	{
+		case s_options:
+			if (!stricmp(name, "usedaodanbsl"))
+				opt_usedaodanbsl = !stricmp(value, "true");
+			break;
 		case s_patch:
 			if (!stricmp(name, "fonttexturecache"))
@@ -227,4 +237,6 @@
 			else if (!stricmp(name, "windowhack"))
 				patch_windowhack = !stricmp(value, "true");
+			else if (!stricmp(name, "daodaninit"))
+				patch_daodaninit = !stricmp(value, "true");
 			else
 				DDrStartupMessage("unrecognised patch \"%s\"", name);
@@ -364,4 +376,10 @@
 }
 
+void ONICALL DDrGame_Init()
+{
+	if (opt_usedaodanbsl)
+		SLrDaodan_Initalize();
+}
+
 void __cdecl DDrMain(int argc, char* argv[])
 {
@@ -400,4 +418,7 @@
 	if (patch_windowhack)
 		DDrWindowHack_Install();
+	
+	if (patch_daodaninit)
+		DDrPatch_MakeCall(OniExe + 0x000d345a, DDrGame_Init);
 	
 	init_daodan_gl();
Index: Daodan/src/Daodan_BSL.c
===================================================================
--- Daodan/src/Daodan_BSL.c	(revision 439)
+++ Daodan/src/Daodan_BSL.c	(revision 439)
@@ -0,0 +1,75 @@
+#include "Daodan_BSL.h"
+#include "BFW_ScriptingLanguage.h"
+
+uint16_t ONICALL bsl_int32mul(void* dontuse0, uint32_t numargs, sl_arg args[], void* dontuse1, void* dontuse2, sl_arg* ret)
+{
+	if (numargs < 2)
+		return 1;
+	ret->value_int32 = args[0].value_int32 * args[1].value_int32;
+	ret->type = sl_int32;
+	return 0;
+}
+
+uint16_t ONICALL bsl_mul(void* dontuse0, uint32_t numargs, sl_arg args[], void* dontuse1, void* dontuse2, sl_arg* ret)
+{
+	if (numargs < 2)
+		return 1;
+	
+	double val1;
+	double val2;
+	
+	if (args[0].type == sl_int32)
+		val1 = args[0].value_int32;
+	else
+		val1 = args[0].value_float;
+	
+	if (args[1].type == sl_int32)
+		val2 = args[1].value_int32;
+	else
+		val2 = args[1].value_float;
+	
+	ret->value_float = (float)(val1 * val2);
+	ret->type = sl_float;
+	return 0;
+}
+
+uint16_t ONICALL bsl_int32div(void* dontuse0, uint32_t numargs, sl_arg args[], void* dontuse1, void* dontuse2, sl_arg* ret)
+{
+	if (numargs < 2)
+		return 1;
+	ret->value_int32 = args[0].value_int32 / args[1].value_int32;
+	ret->type = sl_int32;
+	return 0;
+}
+
+uint16_t ONICALL bsl_div(void* dontuse0, uint32_t numargs, sl_arg args[], void* dontuse1, void* dontuse2, sl_arg* ret)
+{
+	if (numargs < 2)
+		return 1;
+	
+	double val1;
+	double val2;
+	
+	if (args[0].type == sl_int32)
+		val1 = args[0].value_int32;
+	else
+		val1 = args[0].value_float;
+	
+	if (args[1].type == sl_int32)
+		val2 = args[1].value_int32;
+	else
+		val2 = args[1].value_float;
+	
+	ret->value_float = (float)(val1 / val2);
+	ret->type = sl_float;
+	return 0;
+}
+
+void SLrDaodan_Initalize()
+{
+	SLrScript_Command_Register_ReturnType("int32mul", "Multiplies two numbers", "n1:int n2:int", sl_int32, bsl_int32mul);
+	SLrScript_Command_Register_ReturnType("mul", "Multiplies two numbers", "[int1:int|float1:float] [int2:int|float2:float]", sl_float, bsl_mul);
+	
+	SLrScript_Command_Register_ReturnType("int32div", "Divides two numbers", "n1:int n2:int", sl_int32, bsl_int32div);
+	SLrScript_Command_Register_ReturnType("div", "Divides two numbers", "[int1:int|float1:float] [int2:int|float2:float]", sl_float, bsl_div);
+}
Index: Daodan/src/Daodan_BSL.h
===================================================================
--- Daodan/src/Daodan_BSL.h	(revision 439)
+++ Daodan/src/Daodan_BSL.h	(revision 439)
@@ -0,0 +1,9 @@
+#pragma once
+#ifndef DAODAN_BSL_H
+#define DAODAN_BSL_H
+
+#include "Daodan.h"
+
+void SLrDaodan_Initalize();
+
+#endif
Index: Daodan/src/Oni_Symbols.S
===================================================================
--- Daodan/src/Oni_Symbols.S	(revision 438)
+++ Daodan/src/Oni_Symbols.S	(revision 439)
@@ -2,59 +2,62 @@
 
 // MSVC6.0 stdlib
-symbol ( _oni_malloc                         , 0x0011fc24 )
-symbol ( _oni_free                           , 0x0011fbf5 )
+symbol ( _oni_malloc                               , 0x0011fc24 )
+symbol ( _oni_free                                 , 0x0011fbf5 )
 
-symbol ( _oni_fopen                          , 0x0011ea9f )
-symbol ( _oni_fflush                         , 0x0011eab2 )
-symbol ( _oni_fprintf                        , 0x0011ebbf )
-symbol ( _oni_vsprintf                       , 0x0011e860 )
+symbol ( _oni_fopen                                , 0x0011ea9f )
+symbol ( _oni_fflush                               , 0x0011eab2 )
+symbol ( _oni_fprintf                              , 0x0011ebbf )
+symbol ( _oni_vsprintf                             , 0x0011e860 )
 
 // Oni Engine
-symbol ( _ONiMain                            , 0x000d3280 )
-symbol ( @ONrPlatform_Initialize@4           , 0x0010f670 )
-symbol ( _ONrPlatform_WindowProc@16          , 0x0010f7a0 )
+symbol ( _ONiMain                                  , 0x000d3280 )
+symbol ( @ONrPlatform_Initialize@4                 , 0x0010f670 )
+symbol ( _ONrPlatform_WindowProc@16                , 0x0010f7a0 )
 
-symbol ( _g_Instance                         , 0x0021f9e4 )
-symbol ( _ONgPlatformData                    , 0x0023100c )
-symbol ( _ONgGameState                       , 0x001ece7c )
+symbol ( _g_Instance                               , 0x0021f9e4 )
+symbol ( _ONgPlatformData                          , 0x0023100c )
+symbol ( _ONgGameState                             , 0x001ece7c )
 
 //Oni Persistance
-symbol ( @ONrPersist_GetGamma@0              , 0x0010f450 )
-symbol ( @ONrPersist_GetWonGame@0            , 0x0010f660 )
+symbol ( @ONrPersist_GetGamma@0                    , 0x0010f450 )
+symbol ( @ONrPersist_GetWonGame@0                  , 0x0010f660 )
 
 // BFW_Utility
-symbol ( _UUrStartupMessage                  , 0x00024860 )
-symbol ( @UUrMachineTime_High@0              , 0x00026480 )
-symbol ( @UUrMachineTime_High_Frequency@0    , 0x000264b0 )
-symbol ( @UUrMachineTime_Sixtieths@0         , 0x000263e0 )
-symbol ( _ONgFileStartup                     , 0x001711b8 )
+symbol ( _UUrStartupMessage                        , 0x00024860 )
+symbol ( @UUrMachineTime_High@0                    , 0x00026480 )
+symbol ( @UUrMachineTime_High_Frequency@0          , 0x000264b0 )
+symbol ( @UUrMachineTime_Sixtieths@0               , 0x000263e0 )
+symbol ( _ONgFileStartup                           , 0x001711b8 )
 
-symbol ( @UUrPlatform_Initialize@0           , 0x00026010 )
-symbol ( @UUrPlatform_Terminate@0            , 0x00026310 )
+symbol ( @UUrPlatform_Initialize@0                 , 0x00026010 )
+symbol ( @UUrPlatform_Terminate@0                  , 0x00026310 )
 
-symbol ( _AUrMessageBox                      , 0x000378c0 )
+symbol ( _AUrMessageBox                            , 0x000378c0 )
 
 // Motoko
 
-symbol ( _M3gResolutionSwitch                , 0x00131634 )
+symbol ( _M3gResolutionSwitch                      , 0x00131634 )
 
 // OpenGL
-symbol ( @gl_enumerate_valid_display_modes@4 , 0x000083a0 )
-symbol ( @gl_platform_set_pixel_format@4     , 0x00007b50 )
-symbol ( @gl_platform_initialize@0           , 0x00007da0 )
+symbol ( @gl_enumerate_valid_display_modes@4       , 0x000083a0 )
+symbol ( @gl_platform_set_pixel_format@4           , 0x00007b50 )
+symbol ( @gl_platform_initialize@0                 , 0x00007da0 )
 
-symbol ( _gl                                 , 0x00160600 )
-symbol ( _gl_api                             , 0x00160604 )
-symbol ( _gl_gamma_ramp                      , 0x0015fdfc )
-symbol ( _gl_gamma_ramp_valid                , 0x001603fc )
+symbol ( _gl                                       , 0x00160600 )
+symbol ( _gl_api                                   , 0x00160604 )
+symbol ( _gl_gamma_ramp                            , 0x0015fdfc )
+symbol ( _gl_gamma_ramp_valid                      , 0x001603fc )
 
 // Character
-symbol ( @ONrGameState_NewCharacter@16       , 0x000dac50 )
-symbol ( @ONrGameState_GetPlayerCharacter@0  , 0x000b63a7 )
+symbol ( @ONrGameState_NewCharacter@16             , 0x000dac50 )
+symbol ( @ONrGameState_GetPlayerCharacter@0        , 0x000b63a7 )
 
 // Console
-symbol ( @COrTextArea_Print@28               , 0x00031340 )
-symbol ( _COgConsoleLines                    , 0x001cb468 )
-symbol ( _COgFadeTimeValue                   , 0x00133f68 )
-symbol ( _COgDefaultTextShade                , 0x00133f70 )
-symbol ( _COgDefaultTextShadow               , 0x00133f74 )
+symbol ( @COrTextArea_Print@28                     , 0x00031340 )
+symbol ( _COgConsoleLines                          , 0x001cb468 )
+symbol ( _COgFadeTimeValue                         , 0x00133f68 )
+symbol ( _COgDefaultTextShade                      , 0x00133f70 )
+symbol ( _COgDefaultTextShadow                     , 0x00133f74 )
+
+// ScriptingLanguage
+symbol ( @SLrScript_Command_Register_ReturnType@20 , 0x00077b20 )
