1
0
mirror of https://github.com/TerryCavanagh/VVVVVV.git synced 2024-06-28 23:48:30 +02:00
VVVVVV/desktop_version/src/LevelDebugger.cpp

378 lines
12 KiB
C++
Raw Normal View History

#include "LevelDebugger.h"
#include "Constants.h"
#include "Entity.h"
#include "Font.h"
#include "Graphics.h"
#include "KeyPoll.h"
#include "Localization.h"
#include "Map.h"
#include "UtilityClass.h"
#include "VFormat.h"
namespace level_debugger
{
bool active = false;
bool should_pause = true;
bool tab_held = false;
bool debug_held = false;
// Moving entities/blocks
bool mouse_held = false;
int held_entity = -1;
int held_block = -1;
int grabber_offset_x = 0;
int grabber_offset_y = 0;
2023-07-02 16:27:20 +02:00
bool right_mouse_held = false;
bool is_pausing(void)
{
return active && should_pause;
}
bool is_active(void)
{
return active;
}
void toggle_active(void)
{
active = !active;
}
bool mouse_within(SDL_Rect* rect)
{
return key.mx >= rect->x && key.mx < rect->x + rect->w &&
key.my >= rect->y && key.my < rect->y + rect->h;
}
void input(void)
{
if (!map.custommode || map.custommodeforreal)
{
active = false;
return;
}
if (key.isDown(SDLK_y))
{
if (!debug_held)
{
debug_held = true;
active = !active;
}
}
else
{
debug_held = false;
}
if (!active)
{
return;
}
2023-07-02 16:27:20 +02:00
if ((game.press_map || key.isDown(27)) && !game.mapheld)
{
/* If we press enter, allow the rest of the code in Input.cpp to fire
* Intended to return to the editor, but it's fine if it activates
* something instead */
active = false;
return;
}
if (key.isDown(SDLK_TAB))
{
if (!tab_held)
{
tab_held = true;
should_pause = !should_pause;
}
}
else
{
tab_held = false;
}
for (int i = 0; i < obj.entities.size(); i++)
{
SDL_Rect bounding_box = {
obj.entities[i].xp + obj.entities[i].cx,
obj.entities[i].yp + obj.entities[i].cy,
obj.entities[i].w,
obj.entities[i].h
};
if (key.leftbutton)
{
if (mouse_within(&bounding_box))
{
if (!mouse_held)
{
mouse_held = true;
held_entity = i;
grabber_offset_x = key.mx - obj.entities[i].xp;
grabber_offset_y = key.my - obj.entities[i].yp;
if (!key.keymap[SDLK_LSHIFT] && !key.keymap[SDLK_RSHIFT])
{
for (int j = 0; j < obj.blocks.size(); j++)
{
if (obj.entities[i].xp == obj.blocks[j].rect.x && obj.entities[i].yp == obj.blocks[j].rect.y)
{
held_block = j;
}
}
}
}
break;
}
}
else
{
mouse_held = false;
held_entity = -1;
held_block = -1;
}
2023-07-02 16:27:20 +02:00
if (key.rightbutton)
{
if (mouse_within(&bounding_box))
{
if (!right_mouse_held)
{
right_mouse_held = true;
obj.entities[i].state = obj.entities[i].onentity;
obj.entities[i].statedelay = -1;
}
break;
}
}
else
{
right_mouse_held = false;
}
}
if (held_entity == -1)
{
for (int i = 0; i < obj.blocks.size(); i++)
{
SDL_Rect bounding_box = {
obj.blocks[i].rect.x,
obj.blocks[i].rect.y,
obj.blocks[i].rect.w,
obj.blocks[i].rect.h
};
if (key.leftbutton)
{
if (mouse_within(&bounding_box))
{
if (!mouse_held)
{
mouse_held = true;
held_block = i;
grabber_offset_x = key.mx - obj.blocks[i].rect.x;
grabber_offset_y = key.my - obj.blocks[i].rect.y;
}
break;
}
}
else
{
held_entity = -1;
mouse_held = false;
held_block = -1;
}
}
}
if (INBOUNDS_VEC(held_entity, obj.entities))
{
obj.entities[held_entity].xp = key.mx - grabber_offset_x;
obj.entities[held_entity].yp = key.my - grabber_offset_y;
if (key.isDown(SDLK_LSHIFT) || key.isDown(SDLK_RSHIFT))
{
obj.entities[held_entity].xp -= obj.entities[held_entity].xp % 8;
obj.entities[held_entity].yp -= obj.entities[held_entity].yp % 8;
}
}
if (INBOUNDS_VEC(held_block, obj.blocks))
{
int new_xp = key.mx - grabber_offset_x;
int new_yp = key.my - grabber_offset_y;
if (key.isDown(SDLK_LSHIFT) || key.isDown(SDLK_RSHIFT))
{
new_xp -= new_xp % 8;
new_yp -= new_yp % 8;
}
obj.blocks[held_block].xp = new_xp;
obj.blocks[held_block].yp = new_yp;
obj.blocks[held_block].rect.x = new_xp;
obj.blocks[held_block].rect.y = new_yp;
}
}
2023-07-02 16:27:20 +02:00
void render_info(int y, const char* text, std::string value)
{
char buffer[SCREEN_WIDTH_CHARS + 1];
2023-07-02 16:27:20 +02:00
vformat_buf(buffer, sizeof(buffer), text, "value:str", value.c_str());
font::print(PR_BOR | PR_FONT_8X8, 5, 32 + (10 * y), buffer, 220 - (help.glow), 220 - (help.glow), 255 - (help.glow / 2));
}
2023-07-02 16:27:20 +02:00
void render_info(int y, const char* text)
{
font::print(PR_BOR | PR_FONT_8X8, 5, 32 + (10 * y), text, 220 - (help.glow), 220 - (help.glow), 255 - (help.glow / 2));
}
void render(void)
{
if (!active)
{
return;
}
int hovered = -1;
bool hovered_entity = true;
SDL_Rect hover_box;
for (int i = 0; i < obj.entities.size(); i++)
{
SDL_Rect bounding_box = {
obj.entities[i].xp + obj.entities[i].cx,
obj.entities[i].yp + obj.entities[i].cy,
obj.entities[i].w,
obj.entities[i].h
};
bool hovering = false;
if (hovered == -1 && mouse_within(&bounding_box))
{
hovering = true;
hovered = i;
hovered_entity = true;
hover_box = bounding_box;
}
graphics.draw_rect(bounding_box.x, bounding_box.y, bounding_box.w, bounding_box.h, graphics.getRGB(15, 90, 90));
}
for (int i = 0; i < obj.blocks.size(); i++)
{
SDL_Rect bounding_box = {
obj.blocks[i].rect.x,
obj.blocks[i].rect.y,
obj.blocks[i].rect.w,
obj.blocks[i].rect.h
};
bool hovering = false;
if (hovered == -1 && mouse_within(&bounding_box))
{
hovering = true;
hovered = i;
hovered_entity = false;
hover_box = bounding_box;
}
graphics.draw_rect(bounding_box.x, bounding_box.y, bounding_box.w, bounding_box.h, graphics.getRGB(90, 15, 15));
}
font::print(PR_BOR | PR_FONT_8X8, 5, 14, loc::gettext("[Press TAB to toggle movement]"), 220 - (help.glow), 220 - (help.glow), 255 - (help.glow / 2));
if (hovered != -1)
{
int line = 0;
if (hovered_entity)
{
entclass* entity = &obj.entities[hovered];
2023-07-02 16:27:20 +02:00
render_info(line++, "Index: {value}", help.String(hovered));
render_info(line++, "X: {value}", help.String(entity->xp));
render_info(line++, "Y: {value}", help.String(entity->yp));
render_info(line++, "Width: {value}", help.String(entity->w));
render_info(line++, "Height: {value}", help.String(entity->h));
line++;
2023-07-02 16:27:20 +02:00
render_info(line++, "Rule: {value}", help.String(entity->rule));
render_info(line++, "Type: {value}", help.String(entity->type));
render_info(line++, "Behave: {value}", help.String(entity->behave));
render_info(line++, "Para: {value}", help.String(entity->para));
render_info(line++, "State: {value}", help.String(entity->state));
line++;
2023-07-02 16:27:20 +02:00
render_info(line++, "Tile: {value}", help.String(entity->tile));
render_info(line++, "Draw Frame: {value}", help.String(entity->drawframe));
render_info(line++, "Size: {value}", help.String(entity->size));
render_info(line++, "Direction: {value}", help.String(entity->dir));
line++;
// Mostly contains duplicates, but for ease of use
switch (entity->type)
{
case 0:
// Player
render_info(line++, "Gravity: {value}", help.String(game.gravitycontrol));
render_info(line++, "Checkpoint: {value}", help.String(game.savepoint));
break;
case 1:
// Moving platforms and enemies
render_info(line++, "Speed: {value}", help.String(entity->para));
render_info(line++, "Movement type: {value}", help.String(entity->behave));
break;
case 7:
// Trinkets
render_info(line++, "ID: {value}", help.String(entity->para));
break;
case 8:
// Checkpoints
render_info(line++, "ID: {value}", help.String(entity->para));
render_info(line++, "Active: {value}", game.savepoint == entity->para ? "True" : "False");
break;
case 9:
// Horizontal gravity lines
render_info(line++, "Horizontal");
break;
case 10:
// Vertical gravity lines
render_info(line++, "Vertical");
break;
}
graphics.draw_rect(hover_box.x, hover_box.y, hover_box.w, hover_box.h, graphics.getRGB(32, 255 - help.glow, 255 - help.glow));
}
else
{
blockclass* block = &obj.blocks[hovered];
2023-07-02 16:27:20 +02:00
render_info(line++, "Index: {value}", help.String(hovered));
render_info(line++, "X: {value}", help.String(block->rect.x));
render_info(line++, "Y: {value}", help.String(block->rect.y));
render_info(line++, "Width: {value}", help.String(block->rect.w));
render_info(line++, "Height: {value}", help.String(block->rect.h));
line++;
if (block->type == TRIGGER || block->type == ACTIVITY)
{
2023-07-02 16:27:20 +02:00
render_info(line++, "Script: {value}", block->script);
render_info(line++, "State: {value}", help.String(block->trigger));
}
else if (block->type == DIRECTIONAL)
{
2023-07-02 16:27:20 +02:00
render_info(line++, "Direction: {value}", help.String(block->trigger));
}
graphics.draw_rect(hover_box.x, hover_box.y, hover_box.w, hover_box.h, graphics.getRGB(255 - help.glow, 32, 32));
}
}
}
};