📄 cscript.java
字号:
import java.io.*;
import java.util.*;
/**
* <p>Title: Script</p>
* <p>Description: Game Script</p>
* <p>Copyright: CoCoMo Copyright (c) 2006</p>
* <p>HTML: http://spaces.msn.com/j2medev
* <p>Company: 9you</p>
* @author 郭昉
* @version 2.0 Optimized
*/
public class CScript {
// head --------------------------------------------------------------------
public static final String HEAD_BLOCK = "CoCoMo";
// 虚拟机指令 --------------------------------------------------------------------
public static final byte VM_PUSH = 1;
public static final byte VM_POPU = 2;
public static final byte VM_IF = 3;
public static final byte VM_JUMP = 4;
public static final byte VM_PCALL = 5;
public static final byte VM_CALP = 6;
public static final byte VM_RETURN = 8;
public static final byte VM_STOP = 10;
// 关键指令 --------------------------------------------------------------------
public static final int KEYWORD_CALL_ID = -2;
public static final int KEYWORD_LOADSCRIPT_ID = -5;
public static final int KEYWORD_UNLOADSCRIPT_ID = -6;
// 终结符类型-------------------------------------------------------------------
public static final byte T_IDENTIFER = 10; //常量 变量 函数
public static final byte T_INTEGER = 11; //整型
public static final byte T_STRING = 12; //字符型
public static final byte T_BOOLEAN = 13; //布尔型
public static final byte T_OSYMBOL = 15; //操作符号型 > < == >= <=
public static final byte T_RSYMBOL = 16; //关系符号型 && ||
public static final byte T_SCRIPT = 17; //脚本型
// 操作符类型-------------------------------------------------------------------
public static final byte O_EQ = 10; //等于
public static final byte O_NE = 11; //不等于
public static final byte O_LT = 12; //小于
public static final byte O_GT = 13; //大于
public static final byte O_LE = 14; //小于等于
public static final byte O_GE = 15; //大于等于
public static final byte O_OR = 16; //或
public static final byte O_AND = 17; //和
// 条件类型 --------------------------------------------------------------------
public static final byte TRUE = 1;
public static final byte FALSE = 0;
// 数据段-------------------------------------------------------------------
public static short[] m_variable; //变量列表
public static short[][][] m_tData; //数据区
public static StringBuffer m_strbuf = new StringBuffer(); //字符串暂存
// 指令段-------------------------------------------------------------------
public static short[][][] m_script; //脚本数据 格式:[脚本索引][指令索引][参数索引]
// 断点数据 -------------------------------------------------------------------
static short[][] m_recursion; //断点列表 格式:[脚本索引][指令索引]
static int m_recursionLevel; //断点索引
// 控制变量-------------------------------------------------------------------
static short m_curScript; //当前脚本索引
static short m_curIns; //当前指令索引
static boolean b_running; //脚本引擎控制
// 栈 --------------------------------------------------------------------
static short[][] m_stackData; //数据栈
static int m_sDataIndex;
static byte[] m_stackExp; //表达式栈
static int m_sExpIndex;
// 脚本文件 -------------------------------------------------------------------
static String m_file;
public CScript() {
}
//脚本运行前必须调用此函数
public static void init(String file) {
try {
m_file = file;
//支持20级调用 (可修改)
m_recursion = new short[16][2];
m_recursionLevel = 0;
//数据栈槽40 (可修改)
m_stackData = new short[64][];
m_sDataIndex = 0;
//表达式栈槽40
m_stackExp = new byte[32];
m_sExpIndex = 0;
m_curScript = 0;
m_curIns = 0;
LoadScript(m_curScript, false);
b_running = true;
}
catch(Exception e) {
e.printStackTrace();
}
}
//读取文件头 isSkip为真跳过文件头读取
private static void readHead(DataInputStream in, boolean isSkip) {
try {
// Head --------------------------------------------------------------------
String head = in.readUTF();
ASSERT(head.equals(HEAD_BLOCK), "CScript.readHead() -> Unknown File Format");
// 变量-------------------------------------------------------------------
int count = in.readShort();
if(isSkip) {
in.skip(count * 2 + 2); // Include Script Count
}
else {
m_variable = new short[count];
for (int i = 0; i < count; i++) {
m_variable[i] = in.readShort();
}
// Script-------------------------------------------------------------------
count = in.readShort();
m_script = new short[count][][];
// Teminal --------------------------------------------------------------------
m_tData = new short[count][][];
}
}
catch(Exception e) {
e.printStackTrace();
}
}
// -------------------------------------------------------------------
// SCRIPT PART
// -------------------------------------------------------------------
public static void LoadScript(int sNo, boolean isSkip) {
try {
if(isSkip && m_script[sNo] != null) {
return;
}
DataInputStream in = new DataInputStream(m_file.getClass().getResourceAsStream(m_file));
// Head-------------------------------------------------------------------
readHead(in, isSkip);
// Skip-------------------------------------------------------------------
in.skip(sNo * 2);
int off = in.readShort();
in.skip(off);
// 数据 -------------------------------------------------------------------
loadTData(in, sNo);
// 指令 --------------------------------------------------------------------
loadInstruction(in, sNo);
in.close();
in = null;
}
catch(Exception e) {
e.printStackTrace();
}
}
private static void loadTData(DataInputStream in, int sNo) {
try {
int count = in.readShort();
m_tData[sNo] = new short[count][];
for(int i = 0; i < count; i++)
{
byte type = in.readByte();
short value;
short[] data = null;
switch(type) {
case T_IDENTIFER:
case T_INTEGER:
case T_SCRIPT:
value = in.readShort();
data = new short[2];
data[0] = type;
data[1] = value;
break;
case CScript.T_BOOLEAN:
case CScript.T_OSYMBOL:
case CScript.T_RSYMBOL:
value = in.readByte();
data = new short[2];
data[0] = type;
data[1] = value;
break;
case CScript.T_STRING:
short size = in.readShort();
data = new short[size + 2];
data[0] = type;
data[1] = size;
for(int j = 0; j < size; j++) {
data[j + 2] = in.readShort();
}
break;
default:
ASSERT(false, "CScript.loadTData() -> Unknown Teminal Type " + type);
break;
}
ASSERT(data != null, "CScript.loadTData() -> Teminal Data is null");
m_tData[sNo][i] = data;
}
}
catch(Exception e) {
e.printStackTrace();
}
}
private static void loadInstruction(DataInputStream in, int sNo) {
try {
int count = in.readShort();
m_script[sNo] = new short[count][];
for (int i = 0; i < count; i++) {
short id = in.readByte();
if(id == VM_CALP) { //三参数指令
m_script[sNo][i] = new short[4];
m_script[sNo][i][0] = id;
m_script[sNo][i][1] = in.readShort();
m_script[sNo][i][2] = in.readShort();
m_script[sNo][i][3] = in.readShort();
}
else if(id == VM_PCALL) { //双参数指令
m_script[sNo][i] = new short[3];
m_script[sNo][i][0] = id;
m_script[sNo][i][1] = in.readShort();
m_script[sNo][i][2] = in.readShort();
}
else if(id == VM_PUSH ||
id == VM_POPU ||
id == VM_IF ||
id == VM_JUMP) { //单参数指令
m_script[sNo][i] = new short[2];
m_script[sNo][i][0] = id;
m_script[sNo][i][1] = in.readShort();
}
else { //无参数指令
m_script[sNo][i] = new short[1];
m_script[sNo][i][0] = id;
}
}
}
catch(Exception e) {
e.printStackTrace();
}
}
public static void UnLoadScript(int sNo) {
try {
//释放脚本
m_script[sNo] = null;
//释放数据
m_tData[sNo] = null;
System.gc();
}
catch(Exception e) {
e.printStackTrace();
}
}
private static void callCommand() {
//保存断点
m_recursion[m_recursionLevel][0] = m_curScript;
m_recursion[m_recursionLevel][1] = m_curIns;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -