📄 script.cpp
字号:
//
// 执行Script
//
// Copyright (c) 2000-2002 Chihiro.SAKAMOTO (HyperWorks)
//
#include "stdafx.h"
#include <stdlib.h>
#include "MainWin.h"
#include "File.h"
#include "Misc.h"
#include "Script.h"
//
// 错误消息的格式
//
char *__cdecl CScriptAction::Format(const char *fmt, ...)
{
static char tmp[256];
va_list args;
va_start(args, fmt);
vsprintf(tmp, fmt, args);
va_end(args);
return tmp;
}
//
// 初始化
//
void CScriptAction::Initialize(CMainWin *parent, unsigned param1, unsigned param2)
{
CAction::Initialize(parent, param1, param2);
status = Continue;
Pressed = FALSE;
MenuSelect = -1;
PlayMode = param1;
memset(value_tab, 0, sizeof(value_tab));
delete[] script_buffer;
script_buffer = 0;
}
//
// 按下鼠标左键的处理
//
void CScriptAction::LButtonDown(UINT modKeys, CPoint point)
{
switch (status) {
case WaitMenuDone: // 等待菜单
Pressed = TRUE;
break;
}
}
//
// 放开左键的处理
//
void CScriptAction::LButtonUp(UINT modKeys, CPoint point)
{
switch (status) {
case WaitKeyPressed: // 等待按键
Parent->HideWaitMark();
status = Continue;
break;
case WaitMenuDone: // 等待菜单
if (Pressed) {
Pressed = FALSE;
MouseMove(modKeys, point);
if (MenuSelect >= 0) {
SetValue(MenuAnserAddr, Parent->GetMenuAnser(MenuSelect));
Parent->HideMenuWindow();
status = Continue;
}
MenuSelect = -1;
}
break;
}
}
//
// 按下鼠标右键时的处理
//
void CScriptAction::RButtonDown(UINT modKeys, CPoint point)
{
switch (status) {
case WaitKeyPressed: // 等待按键
Parent->FlipMessageWindow();
break;
}
}
//
// 移动右键时的处理
//
void CScriptAction::MouseMove(UINT modKeys, CPoint point)
{
switch (status) {
case WaitMenuDone: // 等待菜单
{
int sel = Parent->GetMenuSelect(point);
if (sel != MenuSelect) {
Parent->SelectMenu(MenuSelect, false);
MenuSelect = sel;
Parent->SelectMenu(MenuSelect, true);
}
}
break;
}
}
//
// 键盘按键按下时的处理
//
void CScriptAction::KeyDown(UINT key)
{
switch (key) {
case VK_RETURN:
case VK_SPACE:
switch (status) {
case WaitKeyPressed: // 等待按键
Parent->HideWaitMark();
status = Continue;
break;
case WaitMenuDone: // 等待菜单
if (MenuSelect >= 0) {
SetValue(MenuAnserAddr, Parent->GetMenuAnser(MenuSelect));
Parent->HideMenuWindow();
status = Continue;
MenuSelect = -1;
}
break;
}
break;
case VK_ESCAPE:
switch (status) {
case WaitKeyPressed: // 等待按键
Parent->FlipMessageWindow();
break;
}
break;
case VK_UP:
if (status == WaitMenuDone) { // 等待菜单
Parent->SelectMenu(MenuSelect, false);
MenuSelect--;
if (MenuSelect < 0)
MenuSelect = Parent->GetMenuItemCount() - 1;
Parent->SelectMenu(MenuSelect, true);
}
break;
case VK_DOWN:
if (status == WaitMenuDone) { // 等待菜单
Parent->SelectMenu(MenuSelect, false);
MenuSelect++;
if (MenuSelect >= Parent->GetMenuItemCount())
MenuSelect = 0;
Parent->SelectMenu(MenuSelect, true);
}
break;
}
}
//
// IDLE处理
//
BOOL CScriptAction::IdleAction()
{
if (status == Continue) { // “继续”执行
do {
status = Step(); // 执行1步
} while (status == Continue) ; // 继续?
if (status == BreakGame) { // 结束
Abort();
}
else if (status == WaitNextIdle) { // 等到下一次IDLE再进来
status = Continue; // 改为继续
return TRUE;
}
}
return FALSE;
}
//
// 结束
//
void CScriptAction::Abort()
{
if (status == WaitMenuDone) // 如果是等待菜单状态
Parent->HideMenuWindow(); // 关闭菜单
Parent->HideMessageWindow(); // 关闭文字框
status = BreakGame;
delete[] script_buffer; // 释放脚本
script_buffer = 0;
Parent->SetAction(CMainWin::ActionScriptDone);
}
//
// 读取脚本档
//
int CScriptAction::LoadFile(const char *name)
{
char path[_MAX_PATH];
sprintf(path, SCRIPTPATH "%s.scr", name);
delete[] script_buffer;
script_buffer = 0;
CFile file(path);
if (!file)
return FileCannotOpen;
int length = file.GetFileSize();
if ((script_buffer = new char [length]) == 0)
return NotEnoughMemory;
if (file.Read(script_buffer, length) != length)
return FileCannotRead;
return FileNoError;
}
//
// 从文件读取脚本,存储脚本的空间也是在这里配置
//
BOOL CScriptAction::Load(const char *name)
{
switch (LoadFile(name)) {
case FileCannotOpen:
Parent->MessageBox(Format("脚本 [%s] 无法开启。", name));
return FALSE;
case NotEnoughMemory:
Parent->MessageBox(Format("内存不足, 无法读取脚本[%s]。", name));
return FALSE;
case FileCannotRead:
Parent->MessageBox(Format("无法读取脚本。[%s]", name));
return FALSE;
}
script_t *header = (script_t *)script_buffer;
if (memcmp(header->magic, SCRIPT_MAGIC, 8) != 0) {
Parent->MessageBox(Format("没有脚本数据。[%s]", name));
return FALSE;
}
current.ncommand = header->ncommand;
current.commands = (byte_t *)(header + 1);
position = 0;
return TRUE;
}
//
// 执行脚本的1步
//
int CScriptAction::Step()
{
ASSERT(script_buffer);
command_t *cmd = GetCommand();
switch (cmd->common.type) {
case SET_VALUE_CMD:
SetValue(cmd->set.value_addr, cmd->set.set_value);
break;
case CALC_VALUE_CMD:
CalcValue(cmd->calc.value_addr, cmd->calc.add_value);
break;
case TEXT_CMD:
Parent->WriteMessage(GetString(cmd->text.msg_len));
return WaitKeyPressed;
case CLEAR_TEXT_CMD:
Parent->ClearMessage();
return WaitNextIdle;
case GOTO_CMD:
GotoCommand(cmd->goto_cmd.goto_label);
break;
case IF_TRUE_CMD:
if (GetValue(cmd->if_cmd.value1, cmd->if_cmd.flag & 1) == GetValue(cmd->if_cmd.value2, cmd->if_cmd.flag & 2))
GotoCommand(cmd->if_cmd.goto_label);
break;
case IF_FALSE_CMD:
if (GetValue(cmd->if_cmd.value1, cmd->if_cmd.flag & 1) != GetValue(cmd->if_cmd.value2, cmd->if_cmd.flag & 2))
GotoCommand(cmd->if_cmd.goto_label);
break;
case IF_BIGGER_CMD:
if (GetValue(cmd->if_cmd.value1, cmd->if_cmd.flag & 1) > GetValue(cmd->if_cmd.value2, cmd->if_cmd.flag & 2))
GotoCommand(cmd->if_cmd.goto_label);
break;
case IF_SMALLER_CMD:
if (GetValue(cmd->if_cmd.value1, cmd->if_cmd.flag & 1) < GetValue(cmd->if_cmd.value2, cmd->if_cmd.flag & 2))
GotoCommand(cmd->if_cmd.goto_label);
break;
case IF_BIGGER_EQU_CMD:
if (GetValue(cmd->if_cmd.value1, cmd->if_cmd.flag & 1) >= GetValue(cmd->if_cmd.value2, cmd->if_cmd.flag & 2))
GotoCommand(cmd->if_cmd.goto_label);
break;
case IF_SMALLER_EQU_CMD:
if (GetValue(cmd->if_cmd.value1, cmd->if_cmd.flag & 1) <= GetValue(cmd->if_cmd.value2, cmd->if_cmd.flag & 2))
GotoCommand(cmd->if_cmd.goto_label);
break;
case MENU_INIT_CMD:
Parent->ClearMenuItemCount();
break;
case MENU_ITEM_CMD:
Parent->SetMenuItem(GetString(cmd->menu_item.label_len), cmd->menu_item.number);
break;
case MENU_CMD:
MenuSelect = -1;
MenuAnserAddr = cmd->menu.value_addr;
Parent->OpenMenu();
return WaitMenuDone;
case EXEC_CMD:
if (!Load(GetString(cmd->exec_cmd.path_len)))
return BreakGame;
PlayMode = MODE_SCENARIO;
break;
case LOAD_CMD:
return LoadGraphic(GetString(cmd->load.path_len), cmd->load.flag);
case UPDATE_CMD:
return UpdateImage();
case CLEAR_CMD:
return Clear(cmd->clear.pos);
case MODE_CMD:
PlayMode = cmd->mode.mode;
break;
case SYS_EXIT_CMD:
Parent->SendMessage(WM_CLOSE);
return WaitNextIdle;
case SYS_CLEAR_CMD:
ClearAllValues();
break;
case END_CMD:
return BreakGame;
default:
ASSERT(false);
break;
}
return Continue;
}
//
// 读取图片档CG
//
int CScriptAction::LoadGraphic(const char *file, int pos)
{
BOOL result = FALSE;
switch (pos) {
case POSITION_BACK: // 背景
Parent->ClearOverlap();
// no break
case POSITION_BACKONLY: // 只有背景
result = Parent->LoadImageBack(file);
break;
case POSITION_CENTER: // 中间
result = Parent->LoadImageCenter(file);
break;
case POSITION_LEFT: // 左
result = Parent->LoadImageLeft(file);
break;
case POSITION_RIGHT: // 右
result = Parent->LoadImageRight(file);
break;
case POSITION_OVERLAP: // 重叠
result = Parent->LoadImageOverlap(file);
break;
}
if (!result) {
Parent->MessageBox(Format("文件无法读取。[%s]", file));
if (PlayMode == MODE_SYSTEM)
Parent->SendMessage(WM_CLOSE);
return BreakGame;
}
return Continue;
}
//
// 清除图片CG
//
int CScriptAction::Clear(int pos)
{
switch (pos) {
case POSITION_BACK: // 背景
Parent->ClearOverlap();
// no break
case POSITION_BACKONLY: // 只有背景
Parent->ClearBack();
break;
case POSITION_CENTER: // 中间
Parent->ClearCenter();
break;
case POSITION_LEFT: // 左
Parent->ClearLeft();
break;
case POSITION_RIGHT: // 右
Parent->ClearRight();
break;
case POSITION_OVERLAP: // 重叠
Parent->ClearOverlap();
break;
}
return Continue;
}
//
// 更新显示
//
int CScriptAction::UpdateImage()
{
CRect rect = Parent->GetInvalidRect();
Parent->UpdateImage(rect);
return WaitNextIdle;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -