You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
240 lines
5.5 KiB
240 lines
5.5 KiB
/*
|
|
OneLoneCoder.com - Sprite Editor
|
|
"Stop Crying about Paint ya big baby" - @Javidx9
|
|
|
|
Disclaimer
|
|
~~~~~~~~~~
|
|
I don't care what you use this for. It's intended to be educational, and perhaps
|
|
to the oddly minded - a little bit of fun. Please hack this, change it and use it
|
|
in any way you see fit. BUT, you acknowledge that I am not responsible for anything
|
|
bad that happens as a result of your actions. However, if good stuff happens, I
|
|
would appreciate a shout out, or at least give the blog some publicity for me.
|
|
Cheers!
|
|
|
|
Background
|
|
~~~~~~~~~~
|
|
Editing ASCII is not a simple as it should be, especially if you want to
|
|
include all the weird characters
|
|
|
|
Controls
|
|
~~~~~~~~
|
|
|
|
|
|
Author
|
|
~~~~~~
|
|
Twitter: @javidx9
|
|
Blog: www.onelonecoder.com
|
|
|
|
Video:
|
|
~~~~~~
|
|
Several...
|
|
|
|
Last Updated:
|
|
*/
|
|
|
|
#include <iostream>
|
|
#include <string>
|
|
using namespace std;
|
|
|
|
#include "olcConsoleGameEngine.h"
|
|
|
|
|
|
|
|
|
|
|
|
class OneLoneCoder_SpriteEditor : public olcConsoleGameEngine
|
|
{
|
|
public:
|
|
OneLoneCoder_SpriteEditor()
|
|
{
|
|
m_sAppName = L"Sprite Editor";
|
|
}
|
|
|
|
private:
|
|
int nPosX = 0;
|
|
int nPosY = 0;
|
|
int nOffsetX = 0;
|
|
int nOffsetY = 0;
|
|
int nZoom = 4;
|
|
int nCurrentGlyph = PIXEL_SOLID;
|
|
int nCurrentColourFG = FG_RED;
|
|
int nCurrentColourBG = FG_BLACK;
|
|
|
|
olcSprite *sprite = nullptr;
|
|
wstring sCurrentSpriteFile;
|
|
|
|
protected:
|
|
// Called by olcConsoleGameEngine
|
|
virtual bool OnUserCreate()
|
|
{
|
|
sprite = new olcSprite(8, 32);
|
|
sCurrentSpriteFile = L"fps_fireball1.spr";
|
|
|
|
return true;
|
|
}
|
|
|
|
// Called by olcConsoleGameEngine
|
|
virtual bool OnUserUpdate(float fElapsedTime)
|
|
{
|
|
|
|
// Zooming
|
|
if (m_keys[VK_PRIOR].bReleased)
|
|
nZoom <<= 1;
|
|
|
|
if (m_keys[VK_NEXT].bReleased)
|
|
nZoom >>= 1;
|
|
|
|
if (nZoom > 32) nZoom = 32;
|
|
if (nZoom < 2) nZoom = 2;
|
|
|
|
// Brushes
|
|
if (m_keys[VK_F1].bReleased) nCurrentGlyph = PIXEL_SOLID;
|
|
if (m_keys[VK_F2].bReleased) nCurrentGlyph = PIXEL_THREEQUARTERS;
|
|
if (m_keys[VK_F3].bReleased) nCurrentGlyph = PIXEL_HALF;
|
|
if (m_keys[VK_F4].bReleased) nCurrentGlyph = PIXEL_QUARTER;
|
|
|
|
// Colours
|
|
for (int i = 0; i < 8; i++)
|
|
if (m_keys[L"01234567"[i]].bReleased)
|
|
if (m_keys[VK_SHIFT].bHeld)
|
|
nCurrentColourFG = i + 8;
|
|
else
|
|
nCurrentColourFG = i;
|
|
|
|
|
|
if (m_keys[VK_F7].bReleased)
|
|
nCurrentColourBG--;
|
|
|
|
if (m_keys[VK_F8].bReleased)
|
|
nCurrentColourBG++;
|
|
|
|
if (nCurrentColourBG < 0) nCurrentColourBG = 15;
|
|
if (nCurrentColourBG > 15) nCurrentColourBG = 0;
|
|
|
|
// Cursing :-)
|
|
if (m_keys[VK_SHIFT].bHeld)
|
|
{
|
|
if (m_keys[VK_UP].bReleased) nOffsetY++;
|
|
if (m_keys[VK_DOWN].bReleased) nOffsetY--;
|
|
if (m_keys[VK_LEFT].bReleased) nOffsetX++;
|
|
if (m_keys[VK_RIGHT].bReleased) nOffsetX--;
|
|
}
|
|
else
|
|
{
|
|
if (m_keys[VK_UP].bReleased) nPosY--;
|
|
if (m_keys[VK_DOWN].bReleased) nPosY++;
|
|
if (m_keys[VK_LEFT].bReleased) nPosX--;
|
|
if (m_keys[VK_RIGHT].bReleased) nPosX++;
|
|
}
|
|
|
|
if (sprite != nullptr)
|
|
{
|
|
if (nPosX < 0) nPosX = 0;
|
|
if (nPosX >= sprite->nWidth) nPosX = sprite->nWidth - 1;
|
|
if (nPosY < 0) nPosY = 0;
|
|
if (nPosY >= sprite->nHeight) nPosY = sprite->nHeight - 1;
|
|
|
|
if (m_keys[VK_SPACE].bReleased)
|
|
{
|
|
sprite->SetGlyph(nPosX - 0, nPosY - 0, nCurrentGlyph);
|
|
sprite->SetColour(nPosX - 0, nPosY - 0, nCurrentColourFG | (nCurrentColourBG << 4));
|
|
}
|
|
|
|
if (m_keys[VK_DELETE].bReleased)
|
|
{
|
|
sprite->SetGlyph(nPosX - 0, nPosY - 0, L' ');
|
|
sprite->SetColour(nPosX - 0, nPosY - 0, 0);
|
|
}
|
|
|
|
if (m_keys[VK_F9].bReleased)
|
|
{
|
|
sprite->Load(sCurrentSpriteFile);
|
|
}
|
|
|
|
if (m_keys[VK_F10].bReleased)
|
|
{
|
|
sprite->Save(sCurrentSpriteFile);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Erase All
|
|
Fill(0, 0, ScreenWidth(), ScreenHeight(), L' ', 0);
|
|
|
|
// Draw Menu
|
|
DrawString(1, 1, L"F1 = 100% F2 = 75% F3 = 50% F4 = 25% F9 = Load File F10 = Save File");
|
|
for (int i = 0; i < 8; i++)
|
|
{
|
|
DrawString(1 + 6 * i, 3, to_wstring(i) + L" = ");
|
|
if (m_keys[VK_SHIFT].bHeld)
|
|
Draw(1 + 6 * i + 4, 3, PIXEL_SOLID, (i + 8));
|
|
else
|
|
Draw(1 + 6 * i + 4, 3, PIXEL_SOLID, (i));
|
|
}
|
|
|
|
DrawString(1, 5, L"Current Brush = ");
|
|
Draw(18, 5, nCurrentGlyph, nCurrentColourFG | (nCurrentColourBG << 4));
|
|
|
|
// Draw Canvas
|
|
for (int x = 9; x < 138; x++)
|
|
{
|
|
Draw(x, 9);
|
|
Draw(x, 74);
|
|
}
|
|
|
|
for (int y = 9; y < 75; y++)
|
|
{
|
|
Draw(9, y);
|
|
Draw(138, y);
|
|
}
|
|
|
|
// Draw Visible Sprite
|
|
if (sprite != nullptr)
|
|
{
|
|
int nVisiblePixelsX = 128 / nZoom;
|
|
int nVisiblePixelsY = 64 / nZoom;
|
|
|
|
for (int x = 0; x < nVisiblePixelsX; x++)
|
|
for (int y = 0; y < nVisiblePixelsY; y++)
|
|
{
|
|
if (x - nOffsetX < sprite->nWidth && y - nOffsetY < sprite->nHeight && x - nOffsetX >= 0 && y - nOffsetY >= 0)
|
|
{
|
|
// Draw Sprite
|
|
Fill(x * nZoom + 10, y*nZoom + 10, (x + 1)*nZoom + 10, (y + 1)*nZoom + 10, sprite->GetGlyph(x - nOffsetX, y - nOffsetY), sprite->GetColour(x - nOffsetX, y - nOffsetY));
|
|
|
|
|
|
// Draw Pixel Markers
|
|
if (sprite->GetGlyph(x - nOffsetX, y - nOffsetY) == L' ')
|
|
Draw((x)* nZoom + 10, (y)* nZoom + 10, L'.');
|
|
}
|
|
|
|
if (x - nOffsetX == nPosX && y - nOffsetY == nPosY)
|
|
Draw((x)* nZoom + 10, (y)* nZoom + 10, L'O');
|
|
}
|
|
}
|
|
|
|
|
|
// Draw Actual Sprite
|
|
for (int x = 0; x < sprite->nWidth; x++)
|
|
for (int y = 0; y < sprite->nHeight; y++)
|
|
Draw(x + 10, y + 80, sprite->GetGlyph(x, y), sprite->GetColour(x, y));
|
|
|
|
|
|
|
|
return true;
|
|
}
|
|
};
|
|
|
|
|
|
int main()
|
|
{
|
|
// Use olcConsoleGameEngine derived app
|
|
OneLoneCoder_SpriteEditor game;
|
|
game.ConstructConsole(160, 100, 8, 8);
|
|
game.Start();
|
|
|
|
return 0;
|
|
} |