// BlockyFroggy
// Copyright © 2017 John Ryland.
// All rights reserved.
#include "EditorState.h"
#include "GameSim.h"
#include "Dialog.h"
#include "Graphics.h"
REGISTER_GAME_STATE(EditorState)
const GameUi::Rectangle paletteRect = { 15, 480, 300, 300 };
const GameUi::Rectangle editorRect = { 335, 555, 300, 150 };
void EditorState::enter(GameGraphics& graphics)
{
std::vector<GameSim::GameObjectList*> objectLists;
graphics.resetVertexBuffers( objectLists );
for (unsigned i = 0; i < sizeof(m_palIdxMru)/sizeof(m_palIdxMru[0]); i++)
m_palIdxMru[i] = 0;
}
void EditorState::exit(GameGraphics& /*graphics*/)
{
}
using namespace GameUi;
void addPixmapData(DrawItems& items, Rectangle screenGeometry, PixelData pixmap, Rectangle pixmapRect)
{
PixelData& m_pixmap = pixmap;
Rectangle& m_pixmapSlice = pixmapRect;
Rectangle& m_geometry = screenGeometry;
if (!m_pixmapSlice.w || !m_pixmapSlice.h)
return;
int pixW = m_geometry.w / m_pixmapSlice.w;
int pixH = m_geometry.h / m_pixmapSlice.h;
for (int j = 0; j < m_pixmapSlice.h; j++)
for (int i = 0; i < m_pixmapSlice.w; i++) {
int x = m_geometry.x + pixW * i;
int y = m_geometry.y + pixH * j;
size_t idx = (m_pixmapSlice.y + j) * m_pixmap.m_stride + m_pixmapSlice.x + i;
if (idx < size_t(m_pixmap.m_stride * m_pixmap.m_rows)) {
if (m_pixmap.m_data[idx].color) {
items.addQuad(Rectangle{x, y, pixW, pixH}, Rectangle{179,113,30,30}, m_pixmap.m_data[idx]);
} else {
items.addQuad(Rectangle{x, y, pixW+1, pixH+1}, Rectangle{179,113,30,30}, 0xaf666666);
items.addQuad(Rectangle{x+pixW/2, y, pixW/2, pixH/2}, Rectangle{180,114,29,29}, 0xafdddddd);
items.addQuad(Rectangle{x, y+pixH/2, pixW/2, pixH/2}, Rectangle{180,114,29,29}, 0xafdddddd);
}
}
}
}
void EditorState::draw(GameGraphics& graphics)
{
static int lastLayer = -11;
int editLayerI = (m_pixD-1) - int((m_pixD-1) * m_editLayer + 0.0);
if (editLayerI != lastLayer || !m_pixels.size())
graphics.getEditObjectPixels(m_editLayer, m_pixels, m_pixW, m_pixH, m_pixD);
else
graphics.setEditObjectPixels(m_editLayer, m_pixels, m_pixW, m_pixH);
lastLayer = editLayerI;
if (!m_palette.size())
graphics.getPalettePixels(m_palette);
int pw = paletteRect.w/16;
int ph = paletteRect.h/16;
int px = m_palIdx%16;
int py = m_palIdx/16;
// Draw bottom ui layer
GameUi::DrawItems itemsUnder;
addPixmapData(itemsUnder, paletteRect, { (GameUi::Color*)m_palette.data(), 16, 16 }, { 0, 0, 16, 16 });
addPixmapData(itemsUnder, editorRect, { (GameUi::Color*)m_pixels.data(), size_t(m_pixW), size_t(m_pixH) }, { 0, 0, m_pixW, m_pixH });
int pixW = (paletteRect.w / 8) - 1;
int pixH = (paletteRect.h / 8) - 1;
for (int i = 0; i < 8; i++)
itemsUnder.addQuad(Rectangle{paletteRect.x + i*pixW, paletteRect.y + 8*pixH, pixW, pixH}, Rectangle{179,113,30,30}, m_palette[m_palIdxMru[i]]);
itemsUnder.addQuad({paletteRect.x + px*pw, paletteRect.y + py*ph, pw, ph}, { 160, 141, 2, 2 }, 0xff123456, 0);
itemsUnder.addIcon(paletteRect.x, paletteRect.y, 23, 0xff123456);
// itemsUnder.addContrastString( 50, 160, "Text under");
graphics.drawAuxItems(itemsUnder);
// Draw 3D parts
graphics.prepareScreenContext();
graphics.setEditLayer(m_editLayer);
graphics.setEditRotation(m_editRotation);
// graphics.setEditModel(editModel);
/*
// Draw ui overlay over everything
GameUi::DrawItems itemsOver;
itemsOver.addContrastString( 70, 220, "Text over");
graphics.drawAuxItems(itemsOver);
*/
}
bool EditorState::update(GameUi::UpdateState& state, float elapsed)
{
//GameUi::Button button(50, 50, "Blah");
//button.onUpdate(items, a_elapsed);
m_editLayer = atof(state.m_variables["EDIT_LAYER"].c_str());
m_editRotation = atof(state.m_variables["EDIT_ROTATION"].c_str());
return true; // has to be exited via ui
}
bool EditorState::touchesChanged(int a_x, int a_y, TouchState ts)
{
/*
if (ts == TouchDown) {
m_touchMoving = false;
m_touchX = a_x;
m_touchY = a_y;
} else if (ts == TouchMove) {
m_touchMoving = true;
} else {
if (m_touchMoving)
{
float dx = m_touchX - a_x;
if (dx > 5 || dx < -5) {
if (dx > 5)
editModel++;
if (dx < -5)
editModel--;
pixels.clear();
}
}
}
*/
if (ts == TouchDown || ts == TouchMove) {
if (paletteRect.isInside({a_x,a_y})) {
int x = (a_x - paletteRect.x) / (paletteRect.w/16);
int y = (a_y - paletteRect.y) / (paletteRect.h/16);
if (x >=0 && x < 16 && y >= 0 && y < 16) {
m_palIdx = y*16+x;
if (m_palIdx != m_palIdxMru[0])
for (int i = (sizeof(m_palIdxMru)/sizeof(m_palIdxMru[0])) -1; i >= 1; i--)
m_palIdxMru[i] = m_palIdxMru[i-1];
m_palIdxMru[0] = m_palIdx;
}
}
else if (m_pixW && m_pixH && editorRect.isInside({a_x,a_y})) {
int x = (a_x - editorRect.x) / (editorRect.w/m_pixW);
int y = (a_y - editorRect.y) / (editorRect.h/m_pixH);
if (x >=0 && x < m_pixW && y >= 0 && y < m_pixH)
m_pixIdx = y*m_pixW+x;
if ( m_palIdx == 0 || m_palIdx == 1 || m_palIdx == 16 || m_palIdx == 17 ) // eraser
m_pixels[m_pixIdx] = 0;
else
m_pixels[m_pixIdx] = m_palette[m_palIdx]; // painting with color
}
}
return false;
}
/*
void clipRendering(int x, int y, int w, int h)
{
GLint vp[4];
glGetIntegerv(GL_VIEWPORT, vp);
GLdouble planes[4][4] = {
{ 1.0, 0.0, 0.0, -2.0 * x / float(vp[2]) + 1.0 }, //left
{ 0.0, -1.0, 0.0, -2.0 * y / float(vp[3]) + 1.0 }, //top
{-1.0, 0.0, 0.0, 2.0 * (x+w) / float(vp[2]) - 1.0 }, //right
{ 0.0, 1.0, 0.0, 2.0 * (y+h) / float(vp[3]) - 1.0 } //bottom
};
for (int i = 0; i < 4; i++) {
glClipPlane(GL_CLIP_PLANE0+i, planes[i]);
glEnable(GL_CLIP_PLANE0+i);
}
}
void disableClip()
{
for (int i = 0; i < 4; i++)
glDisable(GL_CLIP_PLANE0+i);
}
void draw()
{
//clipRendering( 6+2, 55+27, 304, 347 );
GLint vp[4];
glGetIntegerv(GL_VIEWPORT, vp);
glViewport(6+2, vp[3]-(55+27+347), 304, 347);
graphics.drawModelRotatingPreview();
glViewport(vp[0], vp[1], vp[2], vp[3]);
glClear(GL_DEPTH_BUFFER_BIT);
clipRendering(324+2, 55+27, 304, 347 );
graphics.drawModelEditLayer();
disableClip();
}
*/