1
0
Fork 0
mirror of https://github.com/TerryCavanagh/VVVVVV.git synced 2024-12-23 01:59:43 +01:00

Add interpolation to tile tools

This uses DDA (https://w.wiki/6RSQ) to draw a line between the previous
frame's mouse position, and the current frame's mouse position. This
means that there will no longer be gaps in lines of tiles if you move
your mouse fast enough (which is actually rather slow, so it gets
annoying quickly).

The editor's timestep is no longer hardcoded to 24, as I assume that
was only done so there would be less gaps in lines of tiles drawn.
With interpolation, that is no longer an issue, so I've removed the
editor's special case for the timestep.
This commit is contained in:
AllyTally 2023-03-09 14:21:03 -04:00 committed by Misa Elizabeth Kai
parent 6cae666c76
commit d152730510
3 changed files with 37 additions and 8 deletions

View file

@ -81,6 +81,8 @@ void editorclass::reset(void)
direct_mode_drawer = 0; direct_mode_drawer = 0;
entcol = 0; entcol = 0;
old_tilex = 0;
old_tiley = 0;
tilex = 0; tilex = 0;
tiley = 0; tiley = 0;
levx = 0; levx = 0;
@ -1838,6 +1840,31 @@ int editorclass::get_entity_at(int xp, int yp)
return -1; return -1;
} }
static void set_tile_interpolated(const int x1, const int x2, const int y1, const int y2, const int tile)
{
extern editorclass ed;
// draw a line between (x1, y1) and (x2, y2)
const int dx = x2 - x1;
const int dy = y2 - y1;
const int steps = SDL_max(abs(dx), abs(dy));
if (steps == 0)
{
ed.set_tile(x1, y1, tile);
return;
}
for (int i = 0; i <= steps; i++)
{
const int x = x1 + (dx * i) / steps;
const int y = y1 + (dy * i) / steps;
ed.set_tile(x, y, tile);
}
}
void editorclass::handle_tile_placement(const int tile) void editorclass::handle_tile_placement(const int tile)
{ {
@ -1848,7 +1875,7 @@ void editorclass::handle_tile_placement(const int tile)
// Vertical line // Vertical line
for (int i = 0; i < 30; i++) for (int i = 0; i < 30; i++)
{ {
set_tile(tilex, i, tile); set_tile_interpolated(old_tilex, tilex, i, i, tile);
} }
return; return;
} }
@ -1857,7 +1884,7 @@ void editorclass::handle_tile_placement(const int tile)
// Horizontal line // Horizontal line
for (int i = 0; i < 40; i++) for (int i = 0; i < 40; i++)
{ {
set_tile(i, tiley, tile); set_tile_interpolated(i, i, old_tiley, tiley, tile);
} }
return; return;
} }
@ -1879,7 +1906,7 @@ void editorclass::handle_tile_placement(const int tile)
} }
else else
{ {
set_tile(tilex, tiley, tile); set_tile_interpolated(old_tilex, tilex, old_tiley, tiley, tile);
return; return;
} }
@ -1887,7 +1914,7 @@ void editorclass::handle_tile_placement(const int tile)
{ {
for (int j = -range; j <= range; j++) for (int j = -range; j <= range; j++)
{ {
set_tile(tilex + i, tiley + j, tile); set_tile_interpolated(old_tilex + i, tilex + i, old_tiley + j, tiley + j, tile);
} }
} }
} }
@ -1901,7 +1928,7 @@ void editorclass::tool_remove()
handle_tile_placement(0); handle_tile_placement(0);
break; break;
case EditorTool_SPIKES: case EditorTool_SPIKES:
set_tile(tilex, tiley, 0); set_tile_interpolated(old_tilex, tilex, old_tiley, tiley, 0);
break; break;
default: default:
break; break;
@ -2015,7 +2042,7 @@ void editorclass::tool_place()
break; break;
} }
case EditorTool_SPIKES: case EditorTool_SPIKES:
set_tile(tilex, tiley, 8); set_tile_interpolated(old_tilex, tilex, old_tiley, tiley, 8);
break; break;
case EditorTool_TRINKETS: case EditorTool_TRINKETS:
if (cl.numtrinkets() < 100) if (cl.numtrinkets() < 100)
@ -2624,6 +2651,9 @@ void editorinput(void)
return; return;
} }
ed.old_tilex = ed.tilex;
ed.old_tiley = ed.tiley;
ed.tilex = (key.mx - (key.mx % 8)) / 8; ed.tilex = (key.mx - (key.mx % 8)) / 8;
ed.tiley = (key.my - (key.my % 8)) / 8; ed.tiley = (key.my - (key.my % 8)) / 8;

View file

@ -195,6 +195,7 @@ public:
std::string filename; std::string filename;
std::string loaded_filepath; std::string loaded_filepath;
int old_tilex, old_tiley;
int tilex, tiley; int tilex, tiley;
int keydelay, lclickdelay; int keydelay, lclickdelay;
bool savekey, loadkey; bool savekey, loadkey;

View file

@ -7365,8 +7365,6 @@ int Game::get_timestep(void)
{ {
switch (gamestate) switch (gamestate)
{ {
case EDITORMODE:
return 24;
case GAMEMODE: case GAMEMODE:
return get_framerate(slowdown); return get_framerate(slowdown);
default: default: