feat: major engine overhaul - scene demo with lighting, sphere, ground

- Scene Demo: cube + sphere + ground plane with proper lighting
- Audio: XAudio2 dynamic loading + WAV playback
- Physics: expanded collision system
- Renderer: improved pipeline with materials
- UI: extended widget system
- VisualScript: enhanced serializer + block interactions
- ASM: optimized math/memory/profiling routines
- Window: mouse input + scroll support
This commit is contained in:
shuiyu1123 committed 2026-07-12 08:21:07 +08:00
1 parent 2653926d85
commit 0669d102ce
35 files changed
+1844 -314

No files matched your search

+90 -16
View File
@@ -51,6 +51,7 @@ void executor_destroy(BlockExecutor* exec) { free(exec); }
void executor_start(BlockExecutor* exec) {
exec->state = EXEC_RUNNING;
exec->call_stack_top = 0;
exec->loop_stack_top = 0;
exec->current_block = NULL;
for (int i = 0; i < exec->workspace->block_count; i++) {
Block* block = exec->workspace->blocks[i];
@@ -76,6 +77,26 @@ static Block* next_from_output(Block* block, int output_index) {
return NULL;
}
// 查找循环体链的最后一个积木(用于确定循环结束后应跳转到的积木)
static Block* find_loop_body_end(Block* loop_block) {
if (!loop_block || loop_block->output_count == 0 || !loop_block->outputs[0].connected) return NULL;
Block* cur = loop_block->outputs[0].connected->owner;
Block* prev = loop_block;
int guard = 0;
while (cur && guard < 1000) {
guard++;
if (cur == loop_block) return prev; // 回到循环头,则前一个为体尾
Block* next = NULL;
if (cur->output_count > 0 && cur->outputs[0].connected) {
next = cur->outputs[0].connected->owner;
}
if (!next) return cur;
prev = cur;
cur = next;
}
return cur;
}
// 获取值输入
static SlotValue get_input(Block* block, int idx) {
if (idx >= block->input_count) return make_number(0);
@@ -174,22 +195,54 @@ void executor_step(BlockExecutor* exec) {
next = next_from_output(cur, cond ? 0 : 1);
break;
}
case BLOCK_CONTROL_REPEAT: {
case BLOCK_CONTROL_REPEAT:
case BLOCK_CONTROL_WHILE: {
int cond = get_input(cur, 1).as.boolean;
if (cond) next = next_from_output(cur, 0);
else next = next_from_output(cur, 0); // 退出循环: 走输出
LoopFrame* frame = NULL;
if (exec->loop_stack_top > 0 && exec->loop_stack[exec->loop_stack_top - 1].loop_block == cur) {
frame = &exec->loop_stack[exec->loop_stack_top - 1];
} else {
if (exec->loop_stack_top < MAX_LOOP_STACK) {
frame = &exec->loop_stack[exec->loop_stack_top++];
frame->loop_block = cur;
frame->counter = 0;
frame->target = 0;
Block* body_end = find_loop_body_end(cur);
frame->after_block = body_end ? next_from_output(body_end, 0) : NULL;
}
}
if (frame && cond) {
frame->counter++;
next = next_from_output(cur, 0);
} else {
if (frame) exec->loop_stack_top--;
next = frame ? frame->after_block : next_from_output(cur, 0);
}
break;
}
case BLOCK_CONTROL_REPEAT_TIMES: {
double times = get_input(cur, 1).as.number;
// 简化: 只执行一次,实际需要计数器
log_info("循环 %.0f 次 (简化: 执行一次)", times);
next = next_from_output(cur, 0);
break;
}
case BLOCK_CONTROL_WHILE: {
int cond = get_input(cur, 1).as.boolean;
if (cond) next = next_from_output(cur, 0);
LoopFrame* frame = NULL;
if (exec->loop_stack_top > 0 && exec->loop_stack[exec->loop_stack_top - 1].loop_block == cur) {
frame = &exec->loop_stack[exec->loop_stack_top - 1];
frame->counter++;
} else {
if (exec->loop_stack_top < MAX_LOOP_STACK) {
frame = &exec->loop_stack[exec->loop_stack_top++];
frame->loop_block = cur;
frame->counter = 0;
frame->target = (int)times;
Block* body_end = find_loop_body_end(cur);
frame->after_block = body_end ? next_from_output(body_end, 0) : NULL;
}
}
if (frame && frame->counter < frame->target) {
log_info("循环 %d / %d", frame->counter + 1, frame->target);
next = next_from_output(cur, 0);
} else {
if (frame) exec->loop_stack_top--;
next = frame ? frame->after_block : next_from_output(cur, 0);
}
break;
}
case BLOCK_CONTROL_WAIT: {
@@ -320,19 +373,32 @@ void executor_step(BlockExecutor* exec) {
case BLOCK_FUNC_CALL: {
const char* fname = get_input(cur, 1).as.string;
log_info("调用函数 '%s'", fname);
if (exec->call_stack_top < MAX_CALL_STACK) {
// 在工作区中查找同名函数定义积木
Block* def = NULL;
for (int i = 0; i < exec->workspace->block_count; i++) {
Block* b = exec->workspace->blocks[i];
if (b->type == BLOCK_CONTROL_FUNCTION_DEF && strcmp(b->label, fname) == 0) {
def = b;
break;
}
}
if (def && exec->call_stack_top < MAX_CALL_STACK) {
exec->call_stack[exec->call_stack_top].block = cur;
exec->call_stack[exec->call_stack_top].return_block = next_from_output(cur, 0);
exec->call_stack_top++;
next = next_from_output(def, 0);
} else {
if (!def) log_error("未找到函数定义: '%s'", fname);
next = next_from_output(cur, 0);
}
// TODO: 查找函数定义积木并跳转
next = next_from_output(cur, 0);
break;
}
case BLOCK_FUNC_RETURN: {
if (exec->call_stack_top > 0) {
exec->call_stack_top--;
Block* caller = exec->call_stack[exec->call_stack_top].block;
next = next_from_output(caller, 0);
next = exec->call_stack[exec->call_stack_top].return_block;
}
break;
}
@@ -343,6 +409,14 @@ void executor_step(BlockExecutor* exec) {
break;
}
// 若当前 next 是某个活跃循环的 after_block,则跳转回循环头继续判断
if (next && exec->loop_stack_top > 0) {
LoopFrame* frame = &exec->loop_stack[exec->loop_stack_top - 1];
if (next == frame->after_block) {
next = frame->loop_block;
}
}
exec->current_block = next;
if (!exec->current_block) {
log_info("执行完成");