<commit_before>#include <QWindowSystemInterface>
#include "qwaylandintegration.h"
#include "qwaylandwindowsurface.h"

#include <QtGui/private/qpixmap_raster_p.h>
#include <QtGui/QPlatformWindow>

#include <unistd.h>
#include <fcntl.h>
#include <X11/extensions/XKBcommon.h>
#include <X11/keysym.h>

QWaylandInputDevice::QWaylandInputDevice(struct wl_display *display,
					 uint32_t id)
    : mDisplay(display)
    , mInputDevice(wl_input_device_create(display, id))
    , mPointerFocus(NULL)
    , mKeyboardFocus(NULL)
    , mButtons(0)
{
    struct xkb_rule_names names;

    wl_input_device_add_listener(mInputDevice,
				 &inputDeviceListener,
				 this);
    wl_input_device_set_user_data(mInputDevice, this);

    names.rules = "evdev";
    names.model = "pc105";
    names.layout = "us";
    names.variant = "";
    names.options = "";

    mXkb = xkb_compile_keymap_from_rules(&names);
}

void QWaylandInputDevice::inputHandleMotion(void *data,
					    struct wl_input_device *input_device,
					    uint32_t time,
					    int32_t x, int32_t y,
					    int32_t surface_x, int32_t surface_y)
{
    Q_UNUSED(input_device);
    QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
    QWaylandWindow *window = inputDevice->mPointerFocus;

    inputDevice->mSurfacePos = QPoint(surface_x, surface_y);
    inputDevice->mGlobalPos = QPoint(x, y);
    inputDevice->mTime = time;
    QWindowSystemInterface::handleMouseEvent(window->widget(),
					     time,
					     inputDevice->mSurfacePos,
					     inputDevice->mGlobalPos,
					     inputDevice->mButtons);
}

void QWaylandInputDevice::inputHandleButton(void *data,
					    struct wl_input_device *input_device,
					    uint32_t time, uint32_t button, uint32_t state)
{
    Q_UNUSED(input_device);
    QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
    QWaylandWindow *window = inputDevice->mPointerFocus;
    Qt::MouseButton qt_button;

    switch (button) {
    case 272:
	qt_button = Qt::LeftButton;
	break;
    case 273:
	qt_button = Qt::RightButton;
	break;
    case 274:
	qt_button = Qt::MiddleButton;
	break;
    default:
	return;
    }

    if (state)
	inputDevice->mButtons |= qt_button;
    else
	inputDevice->mButtons &= ~qt_button;

    inputDevice->mTime = time;
    QWindowSystemInterface::handleMouseEvent(window->widget(),
					     time,
					     inputDevice->mSurfacePos,
					     inputDevice->mGlobalPos,
					     inputDevice->mButtons);
}

static Qt::KeyboardModifiers translateModifiers(int s)
{
    const uchar qt_alt_mask = XKB_COMMON_MOD1_MASK;
    const uchar qt_meta_mask = XKB_COMMON_MOD4_MASK;

    Qt::KeyboardModifiers ret = 0;
    if (s & XKB_COMMON_SHIFT_MASK)
	ret |= Qt::ShiftModifier;
    if (s & XKB_COMMON_CONTROL_MASK)
	ret |= Qt::ControlModifier;
    if (s & qt_alt_mask)
	ret |= Qt::AltModifier;
    if (s & qt_meta_mask)
	ret |= Qt::MetaModifier;

    return ret;
}

static uint32_t translateKey(uint32_t sym, char *string, size_t size)
{
    string[0] = '\0';

    switch (sym) {
    case XK_Escape:		return Qt::Key_Escape;
    case XK_Tab:		return Qt::Key_Tab;
    case XK_ISO_Left_Tab:	return Qt::Key_Backtab;
    case XK_BackSpace:		return Qt::Key_Backspace;
    case XK_Return:		return Qt::Key_Return;
    case XK_Insert:		return Qt::Key_Insert;
    case XK_Delete:		return Qt::Key_Delete;
    case XK_Clear:		return Qt::Key_Delete;
    case XK_Pause:		return Qt::Key_Pause;
    case XK_Print:		return Qt::Key_Print;

    case XK_Home:		return Qt::Key_Home;
    case XK_End:		return Qt::Key_End;
    case XK_Left:		return Qt::Key_Left;
    case XK_Up:			return Qt::Key_Up;
    case XK_Right:		return Qt::Key_Right;
    case XK_Down:		return Qt::Key_Down;
    case XK_Prior:		return Qt::Key_PageUp;
    case XK_Next:		return Qt::Key_PageDown;

    case XK_Shift_L:		return Qt::Key_Shift;
    case XK_Shift_R:		return Qt::Key_Shift;
    case XK_Shift_Lock:		return Qt::Key_Shift;
    case XK_Control_L:		return Qt::Key_Control;
    case XK_Control_R:		return Qt::Key_Control;
    case XK_Meta_L:		return Qt::Key_Meta;
    case XK_Meta_R:		return Qt::Key_Meta;
    case XK_Alt_L:		return Qt::Key_Alt;
    case XK_Alt_R:		return Qt::Key_Alt;
    case XK_Caps_Lock:		return Qt::Key_CapsLock;
    case XK_Num_Lock:		return Qt::Key_NumLock;
    case XK_Scroll_Lock:	return Qt::Key_ScrollLock;
    case XK_Super_L:		return Qt::Key_Super_L;
    case XK_Super_R:		return Qt::Key_Super_R;
    case XK_Menu:		return Qt::Key_Menu;

    default:
	string[0] = sym;
	string[1] = '\0';
	return toupper(sym);
    }
}

void QWaylandInputDevice::inputHandleKey(void *data,
					 struct wl_input_device *input_device,
					 uint32_t time, uint32_t key, uint32_t state)
{
    Q_UNUSED(input_device);
    QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
    QWaylandWindow *window = inputDevice->mKeyboardFocus;
    uint32_t code, sym, level;
    Qt::KeyboardModifiers modifiers;
    QEvent::Type type;
    char s[2];

    code = key + inputDevice->mXkb->min_key_code;

    level = 0;
    if (inputDevice->mModifiers & Qt::ShiftModifier &&
	XkbKeyGroupWidth(inputDevice->mXkb, code, 0) > 1)
	level = 1;

    sym = XkbKeySymEntry(inputDevice->mXkb, code, level, 0);

    modifiers = translateModifiers(inputDevice->mXkb->map->modmap[code]);

    if (state) {
	inputDevice->mModifiers |= modifiers;
	type = QEvent::KeyPress;
    } else {
	inputDevice->mModifiers &= ~modifiers;
	type = QEvent::KeyRelease;
    }

    sym = translateKey(sym, s, sizeof s);

    qWarning("keycode %d, sym %d, string %d, modifiers 0x%x",
	     code, sym, s[0], (int) inputDevice->mModifiers);

    QWindowSystemInterface::handleKeyEvent(window->widget(),
					   time, type, sym,
					   inputDevice->mModifiers,
					   QString::fromLatin1(s));
}

void QWaylandInputDevice::inputHandlePointerFocus(void *data,
						  struct wl_input_device *input_device,
						  uint32_t time, struct wl_surface *surface,
						  int32_t x, int32_t y, int32_t sx, int32_t sy)
{
    Q_UNUSED(input_device);
    QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
    QWaylandWindow *window;

    if (inputDevice->mPointerFocus) {
	window = inputDevice->mPointerFocus;
	QWindowSystemInterface::handleLeaveEvent(window->widget());
	inputDevice->mPointerFocus = NULL;
    }

    if (surface) {
	window = (QWaylandWindow *) wl_surface_get_user_data(surface);
	QWindowSystemInterface::handleEnterEvent(window->widget());
	inputDevice->mPointerFocus = window;
    }

    inputDevice->mTime = time;
}

void QWaylandInputDevice::inputHandleKeyboardFocus(void *data,
						   struct wl_input_device *input_device,
						   uint32_t time,
						   struct wl_surface *surface,
						   struct wl_array *keys)
{
    Q_UNUSED(input_device);
    QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
    QWaylandWindow *window;

    if (inputDevice->mKeyboardFocus) {
	window = inputDevice->mKeyboardFocus;
	inputDevice->mKeyboardFocus = NULL;
    }

    if (surface) {
	window = (QWaylandWindow *) wl_surface_get_user_data(surface);
	inputDevice->mKeyboardFocus = window;
    }
}

const struct wl_input_device_listener QWaylandInputDevice::inputDeviceListener = {
    QWaylandInputDevice::inputHandleMotion,
    QWaylandInputDevice::inputHandleButton,
    QWaylandInputDevice::inputHandleKey,
    QWaylandInputDevice::inputHandlePointerFocus,
    QWaylandInputDevice::inputHandleKeyboardFocus,
};

void QWaylandInputDevice::attach(QWaylandBuffer *buffer, int x, int y)
{
    wl_input_device_attach(mInputDevice, mTime, buffer->mBuffer, x, y);
}
<commit_msg>Wayland: silence unused variable warnings in qwaylandinputdevice.cpp<commit_after>#include <QWindowSystemInterface>
#include "qwaylandintegration.h"
#include "qwaylandwindowsurface.h"

#include <QtGui/private/qpixmap_raster_p.h>
#include <QtGui/QPlatformWindow>

#include <unistd.h>
#include <fcntl.h>
#include <X11/extensions/XKBcommon.h>
#include <X11/keysym.h>

QWaylandInputDevice::QWaylandInputDevice(struct wl_display *display,
					 uint32_t id)
    : mDisplay(display)
    , mInputDevice(wl_input_device_create(display, id))
    , mPointerFocus(NULL)
    , mKeyboardFocus(NULL)
    , mButtons(0)
{
    struct xkb_rule_names names;

    wl_input_device_add_listener(mInputDevice,
				 &inputDeviceListener,
				 this);
    wl_input_device_set_user_data(mInputDevice, this);

    names.rules = "evdev";
    names.model = "pc105";
    names.layout = "us";
    names.variant = "";
    names.options = "";

    mXkb = xkb_compile_keymap_from_rules(&names);
}

void QWaylandInputDevice::inputHandleMotion(void *data,
					    struct wl_input_device *input_device,
					    uint32_t time,
					    int32_t x, int32_t y,
					    int32_t surface_x, int32_t surface_y)
{
    Q_UNUSED(input_device);
    QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
    QWaylandWindow *window = inputDevice->mPointerFocus;

    inputDevice->mSurfacePos = QPoint(surface_x, surface_y);
    inputDevice->mGlobalPos = QPoint(x, y);
    inputDevice->mTime = time;
    QWindowSystemInterface::handleMouseEvent(window->widget(),
					     time,
					     inputDevice->mSurfacePos,
					     inputDevice->mGlobalPos,
					     inputDevice->mButtons);
}

void QWaylandInputDevice::inputHandleButton(void *data,
					    struct wl_input_device *input_device,
					    uint32_t time, uint32_t button, uint32_t state)
{
    Q_UNUSED(input_device);
    QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
    QWaylandWindow *window = inputDevice->mPointerFocus;
    Qt::MouseButton qt_button;

    switch (button) {
    case 272:
	qt_button = Qt::LeftButton;
	break;
    case 273:
	qt_button = Qt::RightButton;
	break;
    case 274:
	qt_button = Qt::MiddleButton;
	break;
    default:
	return;
    }

    if (state)
	inputDevice->mButtons |= qt_button;
    else
	inputDevice->mButtons &= ~qt_button;

    inputDevice->mTime = time;
    QWindowSystemInterface::handleMouseEvent(window->widget(),
					     time,
					     inputDevice->mSurfacePos,
					     inputDevice->mGlobalPos,
					     inputDevice->mButtons);
}

static Qt::KeyboardModifiers translateModifiers(int s)
{
    const uchar qt_alt_mask = XKB_COMMON_MOD1_MASK;
    const uchar qt_meta_mask = XKB_COMMON_MOD4_MASK;

    Qt::KeyboardModifiers ret = 0;
    if (s & XKB_COMMON_SHIFT_MASK)
	ret |= Qt::ShiftModifier;
    if (s & XKB_COMMON_CONTROL_MASK)
	ret |= Qt::ControlModifier;
    if (s & qt_alt_mask)
	ret |= Qt::AltModifier;
    if (s & qt_meta_mask)
	ret |= Qt::MetaModifier;

    return ret;
}

static uint32_t translateKey(uint32_t sym, char *string, size_t size)
{
    Q_UNUSED(size);
    string[0] = '\0';

    switch (sym) {
    case XK_Escape:		return Qt::Key_Escape;
    case XK_Tab:		return Qt::Key_Tab;
    case XK_ISO_Left_Tab:	return Qt::Key_Backtab;
    case XK_BackSpace:		return Qt::Key_Backspace;
    case XK_Return:		return Qt::Key_Return;
    case XK_Insert:		return Qt::Key_Insert;
    case XK_Delete:		return Qt::Key_Delete;
    case XK_Clear:		return Qt::Key_Delete;
    case XK_Pause:		return Qt::Key_Pause;
    case XK_Print:		return Qt::Key_Print;

    case XK_Home:		return Qt::Key_Home;
    case XK_End:		return Qt::Key_End;
    case XK_Left:		return Qt::Key_Left;
    case XK_Up:			return Qt::Key_Up;
    case XK_Right:		return Qt::Key_Right;
    case XK_Down:		return Qt::Key_Down;
    case XK_Prior:		return Qt::Key_PageUp;
    case XK_Next:		return Qt::Key_PageDown;

    case XK_Shift_L:		return Qt::Key_Shift;
    case XK_Shift_R:		return Qt::Key_Shift;
    case XK_Shift_Lock:		return Qt::Key_Shift;
    case XK_Control_L:		return Qt::Key_Control;
    case XK_Control_R:		return Qt::Key_Control;
    case XK_Meta_L:		return Qt::Key_Meta;
    case XK_Meta_R:		return Qt::Key_Meta;
    case XK_Alt_L:		return Qt::Key_Alt;
    case XK_Alt_R:		return Qt::Key_Alt;
    case XK_Caps_Lock:		return Qt::Key_CapsLock;
    case XK_Num_Lock:		return Qt::Key_NumLock;
    case XK_Scroll_Lock:	return Qt::Key_ScrollLock;
    case XK_Super_L:		return Qt::Key_Super_L;
    case XK_Super_R:		return Qt::Key_Super_R;
    case XK_Menu:		return Qt::Key_Menu;

    default:
	string[0] = sym;
	string[1] = '\0';
	return toupper(sym);
    }
}

void QWaylandInputDevice::inputHandleKey(void *data,
					 struct wl_input_device *input_device,
					 uint32_t time, uint32_t key, uint32_t state)
{
    Q_UNUSED(input_device);
    QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
    QWaylandWindow *window = inputDevice->mKeyboardFocus;
    uint32_t code, sym, level;
    Qt::KeyboardModifiers modifiers;
    QEvent::Type type;
    char s[2];

    code = key + inputDevice->mXkb->min_key_code;

    level = 0;
    if (inputDevice->mModifiers & Qt::ShiftModifier &&
	XkbKeyGroupWidth(inputDevice->mXkb, code, 0) > 1)
	level = 1;

    sym = XkbKeySymEntry(inputDevice->mXkb, code, level, 0);

    modifiers = translateModifiers(inputDevice->mXkb->map->modmap[code]);

    if (state) {
	inputDevice->mModifiers |= modifiers;
	type = QEvent::KeyPress;
    } else {
	inputDevice->mModifiers &= ~modifiers;
	type = QEvent::KeyRelease;
    }

    sym = translateKey(sym, s, sizeof s);

    qWarning("keycode %d, sym %d, string %d, modifiers 0x%x",
	     code, sym, s[0], (int) inputDevice->mModifiers);

    QWindowSystemInterface::handleKeyEvent(window->widget(),
					   time, type, sym,
					   inputDevice->mModifiers,
					   QString::fromLatin1(s));
}

void QWaylandInputDevice::inputHandlePointerFocus(void *data,
						  struct wl_input_device *input_device,
						  uint32_t time, struct wl_surface *surface,
						  int32_t x, int32_t y, int32_t sx, int32_t sy)
{
    Q_UNUSED(input_device);
    Q_UNUSED(x);
    Q_UNUSED(y);
    Q_UNUSED(sx);
    Q_UNUSED(sy);
    QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
    QWaylandWindow *window;

    if (inputDevice->mPointerFocus) {
	window = inputDevice->mPointerFocus;
	QWindowSystemInterface::handleLeaveEvent(window->widget());
	inputDevice->mPointerFocus = NULL;
    }

    if (surface) {
	window = (QWaylandWindow *) wl_surface_get_user_data(surface);
	QWindowSystemInterface::handleEnterEvent(window->widget());
	inputDevice->mPointerFocus = window;
    }

    inputDevice->mTime = time;
}

void QWaylandInputDevice::inputHandleKeyboardFocus(void *data,
						   struct wl_input_device *input_device,
						   uint32_t time,
						   struct wl_surface *surface,
						   struct wl_array *keys)
{
    Q_UNUSED(input_device);
    Q_UNUSED(time);
    Q_UNUSED(keys);
    QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
    QWaylandWindow *window;

    if (inputDevice->mKeyboardFocus) {
	window = inputDevice->mKeyboardFocus;
	inputDevice->mKeyboardFocus = NULL;
    }

    if (surface) {
	window = (QWaylandWindow *) wl_surface_get_user_data(surface);
	inputDevice->mKeyboardFocus = window;
    }
}

const struct wl_input_device_listener QWaylandInputDevice::inputDeviceListener = {
    QWaylandInputDevice::inputHandleMotion,
    QWaylandInputDevice::inputHandleButton,
    QWaylandInputDevice::inputHandleKey,
    QWaylandInputDevice::inputHandlePointerFocus,
    QWaylandInputDevice::inputHandleKeyboardFocus,
};

void QWaylandInputDevice::attach(QWaylandBuffer *buffer, int x, int y)
{
    wl_input_device_attach(mInputDevice, mTime, buffer->mBuffer, x, y);
}
<|endoftext|>


<commit_before>#include <barcode/editorstate.hpp>

#include <barcode/menustate.hpp>
#include <glm/gtx/matrix_decompose.hpp>
#include <hydra/component/rigidbodycomponent.hpp>

using world = Hydra::World::World;
namespace Barcode {
	EditorState::EditorState() : _engine(Hydra::IEngine::getInstance()) {}

	void EditorState::load() {
		_textureLoader = Hydra::IO::GLTextureLoader::create();
		_meshLoader = Hydra::IO::GLMeshLoader::create(_engine->getRenderer());

		auto windowSize = _engine->getView()->getSize();
		_dgp = std::make_unique<DefaultGraphicsPipeline>(_cameraSystem, windowSize);

		{
			_hitboxBatch = RenderBatch<Hydra::Renderer::Batch>("assets/shaders/hitboxdebug.vert", "", "assets/shaders/hitboxdebug.frag", _engine->getView());
			_hitboxBatch.batch.clearFlags = ClearFlags::none;
		}

		{
			_previewBatch = RenderBatch<Hydra::Renderer::Batch>("assets/shaders/previewWindow.vert", "", "assets/shaders/previewWindow.frag", glm::ivec2(720, 720));
			_previewBatch.output->addTexture(0, Hydra::Renderer::TextureType::u8RGB).finalize();
		}
		_initWorld();

		_importerMenu = new ImporterMenu();
		_exporterMenu = new ExporterMenu();
		_componentMenu = new ComponentMenu();
	}

	EditorState::~EditorState() { }

	void EditorState::onMainMenu() {
		if (ImGui::BeginMenu("Editor")) {
			if (ImGui::MenuItem("Import...")) {
				_showImporter = !_showImporter;
				if (_showImporter)
					_importerMenu->refresh("/assets");
			}
			if (ImGui::MenuItem("Export..."))	{
				_showExporter = !_showExporter;
				if (_showExporter)
					_exporterMenu->refresh("/assets");
			}
			if (ImGui::MenuItem("Pathfinding..."))
			{
				_showPathMapCreator = !_showPathMapCreator;
				if (_showPathMapCreator)
				{
					_cc->useOrtho = true;
				}
			}
			if (ImGui::MenuItem("Add component...")){
				_showComponentMenu = !_showComponentMenu;
				if (_showComponentMenu)
					_componentMenu->refresh();
			}
			ImGui::Separator();
			if (ImGui::MenuItem("Clear room")) {
				if (FileTree::getRoomEntity() != nullptr)
					FileTree::getRoomEntity()->dead = true;

				auto room = world::newEntity("Workspace", world::root());
				auto t = room->addComponent<Hydra::Component::TransformComponent>();
				auto r = room->addComponent<Hydra::Component::RoomComponent>();

			}

			ImGui::EndMenu();
		}
	}

	void EditorState::runFrame(float delta) {
		auto windowSize = _engine->getView()->getSize();
		_physicsSystem.tick(delta);
		_cameraSystem.tick(delta);
		_aiSystem.tick(delta);
		_bulletSystem.tick(delta);
		_playerSystem.tick(delta);
		_abilitySystem.tick(delta);
		_particleSystem.tick(delta);
		_rendererSystem.tick(delta);
		_animationSystem.tick(delta);

		const glm::vec3 cameraPos = _playerTransform->position;

		if (_showPathMapCreator)
		{
			_cc->getTransformComponent()->position = glm::vec3(0, 40, 0);
			_cc->cameraPitch = 1.571;
			_cc->cameraYaw = 0;
			_cc->movementSpeed = 0;
			_cc->sensitivity = 0;
		}

		static bool enableHitboxDebug = true;
		ImGui::Checkbox("Enable Hitbox Debug", &enableHitboxDebug);
		ImGui::Checkbox("Enable Glow", &MenuState::glowEnabled);
		ImGui::Checkbox("Enable SSAO", &MenuState::ssaoEnabled);
		ImGui::Checkbox("Enable Shadow", &MenuState::shadowEnabled);

		auto viewMatrix = _cc->getViewMatrix();
		glm::vec3 rightVector = { viewMatrix[0][0], viewMatrix[1][0], viewMatrix[2][0] };
		glm::vec3 upVector = { viewMatrix[0][1], viewMatrix[1][1], viewMatrix[2][1] };
		glm::vec3 forwardVector = { viewMatrix[0][2], viewMatrix[1][2], viewMatrix[2][2] };
		_cameraSystem.setCamInternals(*_cc);
		_cameraSystem.setCamDef(_playerTransform->position, forwardVector, upVector, rightVector, *_cc);

		_dgp->render(cameraPos, *_cc, *_playerTransform);

		if (enableHitboxDebug) {
			for (auto& kv : _hitboxBatch.batch.objects)
				kv.second.clear();

			std::vector<std::shared_ptr<Entity>> entities;
			world::getEntitiesWithComponents<Hydra::Component::RigidBodyComponent, Hydra::Component::DrawObjectComponent>(entities);
			for (auto e : entities) {
				// GOTTA MAKE IT VERSATILE SO IT CAN TAKE CAPSULE AS WELL.
				auto drawObj = e->getComponent<Hydra::Component::DrawObjectComponent>()->drawObject;
				auto rgbc = e->getComponent<Hydra::Component::RigidBodyComponent>();
				glm::vec3 newScale;
				glm::quat rotation;
				glm::vec3 translation;
				glm::vec3 skew;
				glm::vec4 perspective;
				glm::decompose(drawObj->modelMatrix, newScale, rotation, translation, skew, perspective);
				_hitboxBatch.batch.objects[_hitboxCube.get()].push_back(glm::translate(translation) * glm::mat4_cast(rotation) * glm::scale(rgbc->getHalfExtentScale() * glm::vec3(2)));
			}

			world::getEntitiesWithComponents<Hydra::Component::GhostObjectComponent, Hydra::Component::DrawObjectComponent>(entities);
			for (auto e : entities) {
				auto drawObj = e->getComponent<Hydra::Component::DrawObjectComponent>()->drawObject;
				auto goc = e->getComponent<Hydra::Component::GhostObjectComponent>();
				glm::vec3 newScale;
				glm::quat rotation;
				glm::vec3 translation;
				glm::vec3 skew;
				glm::vec4 perspective;
				glm::decompose(drawObj->modelMatrix, newScale, rotation, translation, skew, perspective);
				_hitboxBatch.batch.objects[_hitboxCube.get()].push_back(glm::translate(translation) * glm::mat4_cast(goc->quatRotation) * glm::scale(goc->halfExtents * glm::vec3(2)));
			}

			_hitboxBatch.pipeline->setValue(0, _cc->getViewMatrix());
			_hitboxBatch.pipeline->setValue(1, _cc->getProjectionMatrix());
			_engine->getRenderer()->renderHitboxes(_hitboxBatch.batch);
		}

		if (_showImporter)
			_importerMenu->render(_showImporter, &_previewBatch.batch, delta);
		if (_showExporter)
			_exporterMenu->render(_showExporter);
		if (_showPathMapCreator)
			_pathingMenu.render(_showPathMapCreator, delta, _engine->getView()->getSize().x, _engine->getView()->getSize().y);
		if (_showComponentMenu)
			_componentMenu->render(_showComponentMenu, _physicsSystem);
	}
	void EditorState::_initSystem() {
		const std::vector<Hydra::World::ISystem*> systems = { _engine->getDeadSystem(), &_cameraSystem, &_particleSystem, &_abilitySystem, &_aiSystem, &_physicsSystem, &_bulletSystem, &_playerSystem, &_rendererSystem };
		_engine->getUIRenderer()->registerSystems(systems);
	}
	void EditorState::_initWorld() {
		_hitboxCube = Hydra::IEngine::getInstance()->getState()->getMeshLoader()->getMesh("assets/objects/HitBox.mATTIC");
		{
			auto floor = world::newEntity("Floor", world::root());
			auto t = floor->addComponent<Hydra::Component::TransformComponent>();
			t->position = glm::vec3(0, -7, 0);
			auto rgbc = floor->addComponent<Hydra::Component::RigidBodyComponent>();
			rgbc->createStaticPlane(glm::vec3(0, 1, 0), 1, Hydra::System::BulletPhysicsSystem::CollisionTypes::COLL_WALL
				, 0, 0, 0, 0.6f, 0);
			floor->addComponent<Hydra::Component::MeshComponent>()->loadMesh("assets/objects/Floor_v2.mATTIC");
		}

		{
			auto room = world::newEntity("Workspace", world::root());
			auto t = room->addComponent<Hydra::Component::TransformComponent>();
			auto r = room->addComponent<Hydra::Component::RoomComponent>();
		}

		{
			auto compass = world::newEntity("Compass", world::root());
			auto t = compass->addComponent<Hydra::Component::TransformComponent>();

			auto n = world::newEntity("North", compass);
			auto tn = n->addComponent<Hydra::Component::TransformComponent>();
			tn->position = glm::vec3(0,0,17);

			auto e = world::newEntity("East", compass);
			auto te = e->addComponent<Hydra::Component::TransformComponent>();
			te->position = glm::vec3(17, 0, 0);

			auto s = world::newEntity("South", compass);
			auto ts = s->addComponent<Hydra::Component::TransformComponent>();
			ts->position = glm::vec3(0, 0, -17);

			auto w = world::newEntity("West", compass);
			auto tw = w->addComponent<Hydra::Component::TransformComponent>();
			tw->position = glm::vec3(-17, 0, 0);
		}

		{
			auto playerEntity = world::newEntity("Player", world::root());
			auto c = playerEntity->addComponent<Hydra::Component::CameraComponent>();
			c->noClip = true;
			c->mouseControl = false;
			auto t = playerEntity->addComponent<Hydra::Component::TransformComponent>();
			_playerTransform = t.get();
		}

		{
			auto lightEntity = world::newEntity("Light", world::root());
			auto l = lightEntity->addComponent<Hydra::Component::LightComponent>();
			auto t = lightEntity->addComponent<Hydra::Component::TransformComponent>();
			t->position = glm::vec3(8.0, 0, 3.5);
		}

		{
			BlueprintLoader::save("world.blueprint", "World Blueprint", world::root().get());
			Hydra::World::World::reset();
			auto bp = BlueprintLoader::load("world.blueprint");
			bp->spawn(world::root());
		}

		{
			_cc = static_cast<Hydra::Component::CameraComponent*>(Hydra::Component::CameraComponent::componentHandler->getActiveComponents()[0].get());
			for (auto& rb : Hydra::Component::RigidBodyComponent::componentHandler->getActiveComponents()) {
				_engine->log(Hydra::LogLevel::normal, "Enabling bullet for %s", world::getEntity(rb->entityID)->name.c_str());
				_physicsSystem.enable(static_cast<Hydra::Component::RigidBodyComponent*>(rb.get()));
			}
		}
	}
}
<commit_msg>editorstate font fix<commit_after>#include <barcode/editorstate.hpp>

#include <barcode/menustate.hpp>
#include <glm/gtx/matrix_decompose.hpp>
#include <hydra/component/rigidbodycomponent.hpp>

using world = Hydra::World::World;
namespace Barcode {
	EditorState::EditorState() : _engine(Hydra::IEngine::getInstance()) {}

	void EditorState::load() {
		_textureLoader = Hydra::IO::GLTextureLoader::create();
		_meshLoader = Hydra::IO::GLMeshLoader::create(_engine->getRenderer());
		_textFactory = Hydra::IO::GLTextFactory::create("assets/fonts/font.png");
		auto windowSize = _engine->getView()->getSize();
		_dgp = std::make_unique<DefaultGraphicsPipeline>(_cameraSystem, windowSize);

		{
			_hitboxBatch = RenderBatch<Hydra::Renderer::Batch>("assets/shaders/hitboxdebug.vert", "", "assets/shaders/hitboxdebug.frag", _engine->getView());
			_hitboxBatch.batch.clearFlags = ClearFlags::none;
		}

		{
			_previewBatch = RenderBatch<Hydra::Renderer::Batch>("assets/shaders/previewWindow.vert", "", "assets/shaders/previewWindow.frag", glm::ivec2(720, 720));
			_previewBatch.output->addTexture(0, Hydra::Renderer::TextureType::u8RGB).finalize();
		}
		_initWorld();

		_importerMenu = new ImporterMenu();
		_exporterMenu = new ExporterMenu();
		_componentMenu = new ComponentMenu();
	}

	EditorState::~EditorState() { }

	void EditorState::onMainMenu() {
		if (ImGui::BeginMenu("Editor")) {
			if (ImGui::MenuItem("Import...")) {
				_showImporter = !_showImporter;
				if (_showImporter)
					_importerMenu->refresh("/assets");
			}
			if (ImGui::MenuItem("Export..."))	{
				_showExporter = !_showExporter;
				if (_showExporter)
					_exporterMenu->refresh("/assets");
			}
			if (ImGui::MenuItem("Pathfinding..."))
			{
				_showPathMapCreator = !_showPathMapCreator;
				if (_showPathMapCreator)
				{
					_cc->useOrtho = true;
				}
			}
			if (ImGui::MenuItem("Add component...")){
				_showComponentMenu = !_showComponentMenu;
				if (_showComponentMenu)
					_componentMenu->refresh();
			}
			ImGui::Separator();
			if (ImGui::MenuItem("Clear room")) {
				if (FileTree::getRoomEntity() != nullptr)
					FileTree::getRoomEntity()->dead = true;

				auto room = world::newEntity("Workspace", world::root());
				auto t = room->addComponent<Hydra::Component::TransformComponent>();
				auto r = room->addComponent<Hydra::Component::RoomComponent>();

			}

			ImGui::EndMenu();
		}
	}

	void EditorState::runFrame(float delta) {
		auto windowSize = _engine->getView()->getSize();
		_physicsSystem.tick(delta);
		_cameraSystem.tick(delta);
		_aiSystem.tick(delta);
		_bulletSystem.tick(delta);
		_playerSystem.tick(delta);
		_abilitySystem.tick(delta);
		_particleSystem.tick(delta);
		_rendererSystem.tick(delta);
		_animationSystem.tick(delta);

		const glm::vec3 cameraPos = _playerTransform->position;

		if (_showPathMapCreator)
		{
			_cc->getTransformComponent()->position = glm::vec3(0, 40, 0);
			_cc->cameraPitch = 1.571;
			_cc->cameraYaw = 0;
			_cc->movementSpeed = 0;
			_cc->sensitivity = 0;
		}

		static bool enableHitboxDebug = true;
		ImGui::Checkbox("Enable Hitbox Debug", &enableHitboxDebug);
		ImGui::Checkbox("Enable Glow", &MenuState::glowEnabled);
		ImGui::Checkbox("Enable SSAO", &MenuState::ssaoEnabled);
		ImGui::Checkbox("Enable Shadow", &MenuState::shadowEnabled);

		auto viewMatrix = _cc->getViewMatrix();
		glm::vec3 rightVector = { viewMatrix[0][0], viewMatrix[1][0], viewMatrix[2][0] };
		glm::vec3 upVector = { viewMatrix[0][1], viewMatrix[1][1], viewMatrix[2][1] };
		glm::vec3 forwardVector = { viewMatrix[0][2], viewMatrix[1][2], viewMatrix[2][2] };
		_cameraSystem.setCamInternals(*_cc);
		_cameraSystem.setCamDef(_playerTransform->position, forwardVector, upVector, rightVector, *_cc);

		_dgp->render(cameraPos, *_cc, *_playerTransform);

		if (enableHitboxDebug) {
			for (auto& kv : _hitboxBatch.batch.objects)
				kv.second.clear();

			std::vector<std::shared_ptr<Entity>> entities;
			world::getEntitiesWithComponents<Hydra::Component::RigidBodyComponent, Hydra::Component::DrawObjectComponent>(entities);
			for (auto e : entities) {
				// GOTTA MAKE IT VERSATILE SO IT CAN TAKE CAPSULE AS WELL.
				auto drawObj = e->getComponent<Hydra::Component::DrawObjectComponent>()->drawObject;
				auto rgbc = e->getComponent<Hydra::Component::RigidBodyComponent>();
				glm::vec3 newScale;
				glm::quat rotation;
				glm::vec3 translation;
				glm::vec3 skew;
				glm::vec4 perspective;
				glm::decompose(drawObj->modelMatrix, newScale, rotation, translation, skew, perspective);
				_hitboxBatch.batch.objects[_hitboxCube.get()].push_back(glm::translate(translation) * glm::mat4_cast(rotation) * glm::scale(rgbc->getHalfExtentScale() * glm::vec3(2)));
			}

			world::getEntitiesWithComponents<Hydra::Component::GhostObjectComponent, Hydra::Component::DrawObjectComponent>(entities);
			for (auto e : entities) {
				auto drawObj = e->getComponent<Hydra::Component::DrawObjectComponent>()->drawObject;
				auto goc = e->getComponent<Hydra::Component::GhostObjectComponent>();
				glm::vec3 newScale;
				glm::quat rotation;
				glm::vec3 translation;
				glm::vec3 skew;
				glm::vec4 perspective;
				glm::decompose(drawObj->modelMatrix, newScale, rotation, translation, skew, perspective);
				_hitboxBatch.batch.objects[_hitboxCube.get()].push_back(glm::translate(translation) * glm::mat4_cast(goc->quatRotation) * glm::scale(goc->halfExtents * glm::vec3(2)));
			}

			_hitboxBatch.pipeline->setValue(0, _cc->getViewMatrix());
			_hitboxBatch.pipeline->setValue(1, _cc->getProjectionMatrix());
			_engine->getRenderer()->renderHitboxes(_hitboxBatch.batch);
		}

		if (_showImporter)
			_importerMenu->render(_showImporter, &_previewBatch.batch, delta);
		if (_showExporter)
			_exporterMenu->render(_showExporter);
		if (_showPathMapCreator)
			_pathingMenu.render(_showPathMapCreator, delta, _engine->getView()->getSize().x, _engine->getView()->getSize().y);
		if (_showComponentMenu)
			_componentMenu->render(_showComponentMenu, _physicsSystem);
	}
	void EditorState::_initSystem() {
		const std::vector<Hydra::World::ISystem*> systems = { _engine->getDeadSystem(), &_cameraSystem, &_particleSystem, &_abilitySystem, &_aiSystem, &_physicsSystem, &_bulletSystem, &_playerSystem, &_rendererSystem };
		_engine->getUIRenderer()->registerSystems(systems);
	}
	void EditorState::_initWorld() {
		_hitboxCube = Hydra::IEngine::getInstance()->getState()->getMeshLoader()->getMesh("assets/objects/HitBox.mATTIC");
		{
			auto floor = world::newEntity("Floor", world::root());
			auto t = floor->addComponent<Hydra::Component::TransformComponent>();
			t->position = glm::vec3(0, -7, 0);
			auto rgbc = floor->addComponent<Hydra::Component::RigidBodyComponent>();
			rgbc->createStaticPlane(glm::vec3(0, 1, 0), 1, Hydra::System::BulletPhysicsSystem::CollisionTypes::COLL_WALL
				, 0, 0, 0, 0.6f, 0);
			floor->addComponent<Hydra::Component::MeshComponent>()->loadMesh("assets/objects/Floor_v2.mATTIC");
		}

		{
			auto room = world::newEntity("Workspace", world::root());
			auto t = room->addComponent<Hydra::Component::TransformComponent>();
			auto r = room->addComponent<Hydra::Component::RoomComponent>();
		}

		{
			auto compass = world::newEntity("Compass", world::root());
			auto t = compass->addComponent<Hydra::Component::TransformComponent>();

			auto n = world::newEntity("North", compass);
			auto tn = n->addComponent<Hydra::Component::TransformComponent>();
			tn->position = glm::vec3(0,0,17);

			auto e = world::newEntity("East", compass);
			auto te = e->addComponent<Hydra::Component::TransformComponent>();
			te->position = glm::vec3(17, 0, 0);

			auto s = world::newEntity("South", compass);
			auto ts = s->addComponent<Hydra::Component::TransformComponent>();
			ts->position = glm::vec3(0, 0, -17);

			auto w = world::newEntity("West", compass);
			auto tw = w->addComponent<Hydra::Component::TransformComponent>();
			tw->position = glm::vec3(-17, 0, 0);
		}

		{
			auto playerEntity = world::newEntity("Player", world::root());
			auto c = playerEntity->addComponent<Hydra::Component::CameraComponent>();
			c->noClip = true;
			c->mouseControl = false;
			auto t = playerEntity->addComponent<Hydra::Component::TransformComponent>();
			_playerTransform = t.get();
		}

		{
			auto lightEntity = world::newEntity("Light", world::root());
			auto l = lightEntity->addComponent<Hydra::Component::LightComponent>();
			auto t = lightEntity->addComponent<Hydra::Component::TransformComponent>();
			t->position = glm::vec3(8.0, 0, 3.5);
		}

		{
			BlueprintLoader::save("world.blueprint", "World Blueprint", world::root().get());
			Hydra::World::World::reset();
			auto bp = BlueprintLoader::load("world.blueprint");
			bp->spawn(world::root());
		}

		{
			_cc = static_cast<Hydra::Component::CameraComponent*>(Hydra::Component::CameraComponent::componentHandler->getActiveComponents()[0].get());
			for (auto& rb : Hydra::Component::RigidBodyComponent::componentHandler->getActiveComponents()) {
				_engine->log(Hydra::LogLevel::normal, "Enabling bullet for %s", world::getEntity(rb->entityID)->name.c_str());
				_physicsSystem.enable(static_cast<Hydra::Component::RigidBodyComponent*>(rb.get()));
			}
		}
	}
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2006 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "base/trace.hh"
#include "dev/io_device.hh"
#include "sim/builder.hh"

PioPort::PioPort(PioDevice *dev, Platform *p)
    : Port(dev->name() + "-pioport"), device(dev), platform(p)
{ }

Tick
PioPort::recvAtomic(Packet *pkt)
{
    return device->recvAtomic(pkt);
}

void
PioPort::recvFunctional(Packet *pkt)
{
    device->recvAtomic(pkt);
}

void
PioPort::getDeviceAddressRanges(AddrRangeList &resp, AddrRangeList &snoop)
{
    snoop.clear();
    device->addressRanges(resp);
}

void
PioPort::recvRetry()
{
    Packet* pkt = transmitList.front();
    if (Port::sendTiming(pkt)) {
        transmitList.pop_front();
    }
}

void
PioPort::SendEvent::process()
{
    if (port->Port::sendTiming(packet))
        return;

    port->transmitList.push_back(packet);
}

bool
PioPort::recvTiming(Packet *pkt)
{
    device->recvAtomic(pkt);
    // turn packet around to go back to requester
    pkt->makeTimingResponse();
    sendTiming(pkt, pkt->time - pkt->req->getTime());
    return true;
}

PioDevice::~PioDevice()
{
    if (pioPort)
        delete pioPort;
}

void
PioDevice::init()
{
    if (!pioPort)
        panic("Pio port not connected to anything!");
    pioPort->sendStatusChange(Port::RangeChange);
}

void
BasicPioDevice::addressRanges(AddrRangeList &range_list)
{
    assert(pioSize != 0);
    range_list.clear();
    range_list.push_back(RangeSize(pioAddr, pioSize));
}

DmaPort::DmaPort(DmaDevice *dev, Platform *p)
    : Port(dev->name() + "-dmaport"), device(dev), platform(p), pendingCount(0)
{ }

bool
DmaPort::recvTiming(Packet *pkt)
{
    if (pkt->senderState) {
        DmaReqState *state;
        DPRINTF(DMA, "Received response Packet %#x with senderState: %#x\n",
               pkt, pkt->senderState);
        state = dynamic_cast<DmaReqState*>(pkt->senderState);
        assert(state);
        state->completionEvent->process();
        delete pkt->req;
        delete pkt;
    }  else {
        DPRINTF(DMA, "Received response Packet %#x with no senderState\n", pkt);
        delete pkt->req;
        delete pkt;
    }

    return true;
}

DmaDevice::DmaDevice(Params *p)
    : PioDevice(p), dmaPort(NULL)
{ }

void
DmaPort::recvRetry()
{
    Packet* pkt = transmitList.front();
    DPRINTF(DMA, "Retry on  Packet %#x with senderState: %#x\n",
               pkt, pkt->senderState);
    if (sendTiming(pkt)) {
        DPRINTF(DMA, "-- Done\n");
        transmitList.pop_front();
        pendingCount--;
        assert(pendingCount >= 0);
    } else {
        DPRINTF(DMA, "-- Failed, queued\n");
    }
}

void
DmaPort::dmaAction(Packet::Command cmd, Addr addr, int size, Event *event,
                   uint8_t *data)
{
    assert(event);

    int prevSize = 0;

    for (ChunkGenerator gen(addr, size, peerBlockSize());
         !gen.done(); gen.next()) {
            Request *req = new Request(false);
            req->setPaddr(gen.addr());
            req->setSize(gen.size());
            req->setTime(curTick);
            Packet *pkt = new Packet(req, cmd, Packet::Broadcast);

            // Increment the data pointer on a write
            if (data)
                pkt->dataStatic(data + prevSize) ;

            prevSize += gen.size();

            // Set the last bit of the dma as the final packet for this dma
            // and set it's completion event.
            if (prevSize == size) {
                pkt->senderState = new DmaReqState(event, true);
            }
            assert(pendingCount >= 0);
            pendingCount++;
            sendDma(pkt);
    }
}

void
DmaPort::sendDma(Packet *pkt)
{
   // some kind of selction between access methods
   // more work is going to have to be done to make
   // switching actually work
  /* MemState state = device->platform->system->memState;

   if (state == Timing) {  */
       DPRINTF(DMA, "Attempting to send Packet %#x with senderState: %#x\n",
               pkt, pkt->senderState);
       if (!sendTiming(pkt)) {
           transmitList.push_back(pkt);
           DPRINTF(DMA, "-- Failed: queued\n");
       } else {
           DPRINTF(DMA, "-- Done\n");
           pendingCount--;
           assert(pendingCount >= 0);
       }
  /*  } else if (state == Atomic) {
       sendAtomic(pkt);
       if (pkt->senderState) {
           DmaReqState *state = dynamic_cast<DmaReqState*>(pkt->senderState);
           assert(state);
           state->completionEvent->schedule(curTick + (pkt->time - pkt->req->getTime()) +1);
       }
       pendingCount--;
       assert(pendingCount >= 0);
       delete pkt->req;
       delete pkt;

   } else if (state == Functional) {
       sendFunctional(pkt);
       // Is this correct???
       completionEvent->schedule(pkt->req->responseTime - pkt->req->requestTime);
       completionEvent == NULL;
   } else
       panic("Unknown memory command state.");
  */
}

DmaDevice::~DmaDevice()
{
    if (dmaPort)
        delete dmaPort;
}

<commit_msg>make io device be a little nicer about scheduling retries on the bus<commit_after>/*
 * Copyright (c) 2006 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "base/trace.hh"
#include "dev/io_device.hh"
#include "sim/builder.hh"

PioPort::PioPort(PioDevice *dev, Platform *p)
    : Port(dev->name() + "-pioport"), device(dev), platform(p)
{ }

Tick
PioPort::recvAtomic(Packet *pkt)
{
    return device->recvAtomic(pkt);
}

void
PioPort::recvFunctional(Packet *pkt)
{
    device->recvAtomic(pkt);
}

void
PioPort::getDeviceAddressRanges(AddrRangeList &resp, AddrRangeList &snoop)
{
    snoop.clear();
    device->addressRanges(resp);
}

void
PioPort::recvRetry()
{
    Packet* pkt = transmitList.front();
    if (Port::sendTiming(pkt)) {
        transmitList.pop_front();
    }
}

void
PioPort::SendEvent::process()
{
    if (port->Port::sendTiming(packet))
        return;

    port->transmitList.push_back(packet);
}

bool
PioPort::recvTiming(Packet *pkt)
{
    device->recvAtomic(pkt);
    // turn packet around to go back to requester
    pkt->makeTimingResponse();
    sendTiming(pkt, pkt->time - pkt->req->getTime());
    return true;
}

PioDevice::~PioDevice()
{
    if (pioPort)
        delete pioPort;
}

void
PioDevice::init()
{
    if (!pioPort)
        panic("Pio port not connected to anything!");
    pioPort->sendStatusChange(Port::RangeChange);
}

void
BasicPioDevice::addressRanges(AddrRangeList &range_list)
{
    assert(pioSize != 0);
    range_list.clear();
    range_list.push_back(RangeSize(pioAddr, pioSize));
}

DmaPort::DmaPort(DmaDevice *dev, Platform *p)
    : Port(dev->name() + "-dmaport"), device(dev), platform(p), pendingCount(0)
{ }

bool
DmaPort::recvTiming(Packet *pkt)
{
    if (pkt->senderState) {
        DmaReqState *state;
        DPRINTF(DMA, "Received response Packet %#x with senderState: %#x\n",
               pkt, pkt->senderState);
        state = dynamic_cast<DmaReqState*>(pkt->senderState);
        assert(state);
        state->completionEvent->process();
        delete pkt->req;
        delete pkt;
    }  else {
        DPRINTF(DMA, "Received response Packet %#x with no senderState\n", pkt);
        delete pkt->req;
        delete pkt;
    }

    return true;
}

DmaDevice::DmaDevice(Params *p)
    : PioDevice(p), dmaPort(NULL)
{ }

void
DmaPort::recvRetry()
{
    Packet* pkt = transmitList.front();
    bool result = true;
    while (result && transmitList.size()) {
        DPRINTF(DMA, "Retry on  Packet %#x with senderState: %#x\n",
                   pkt, pkt->senderState);
        result = sendTiming(pkt);
        if (result) {
            DPRINTF(DMA, "-- Done\n");
            transmitList.pop_front();
            pendingCount--;
            assert(pendingCount >= 0);
        } else {
            DPRINTF(DMA, "-- Failed, queued\n");
        }
    }
}

void
DmaPort::dmaAction(Packet::Command cmd, Addr addr, int size, Event *event,
                   uint8_t *data)
{
    assert(event);

    int prevSize = 0;

    for (ChunkGenerator gen(addr, size, peerBlockSize());
         !gen.done(); gen.next()) {
            Request *req = new Request(false);
            req->setPaddr(gen.addr());
            req->setSize(gen.size());
            req->setTime(curTick);
            Packet *pkt = new Packet(req, cmd, Packet::Broadcast);

            // Increment the data pointer on a write
            if (data)
                pkt->dataStatic(data + prevSize) ;

            prevSize += gen.size();

            // Set the last bit of the dma as the final packet for this dma
            // and set it's completion event.
            if (prevSize == size) {
                pkt->senderState = new DmaReqState(event, true);
            }
            assert(pendingCount >= 0);
            pendingCount++;
            sendDma(pkt);
    }
}

void
DmaPort::sendDma(Packet *pkt)
{
   // some kind of selction between access methods
   // more work is going to have to be done to make
   // switching actually work
  /* MemState state = device->platform->system->memState;

   if (state == Timing) {  */
       DPRINTF(DMA, "Attempting to send Packet %#x with senderState: %#x\n",
               pkt, pkt->senderState);
       if (transmitList.size() || !sendTiming(pkt)) {
           transmitList.push_back(pkt);
           DPRINTF(DMA, "-- Failed: queued\n");
       } else {
           DPRINTF(DMA, "-- Done\n");
           pendingCount--;
           assert(pendingCount >= 0);
       }
  /*  } else if (state == Atomic) {
       sendAtomic(pkt);
       if (pkt->senderState) {
           DmaReqState *state = dynamic_cast<DmaReqState*>(pkt->senderState);
           assert(state);
           state->completionEvent->schedule(curTick + (pkt->time - pkt->req->getTime()) +1);
       }
       pendingCount--;
       assert(pendingCount >= 0);
       delete pkt->req;
       delete pkt;

   } else if (state == Functional) {
       sendFunctional(pkt);
       // Is this correct???
       completionEvent->schedule(pkt->req->responseTime - pkt->req->requestTime);
       completionEvent == NULL;
   } else
       panic("Unknown memory command state.");
  */
}

DmaDevice::~DmaDevice()
{
    if (dmaPort)
        delete dmaPort;
}

<|endoftext|>


<commit_before>/*
 * Copyright (c) 2006 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Ali Saidi
 */

/** @file
 * This device implemetns the niagara I/O bridge chip. It manages incomming
 * interrupts and posts them to the CPU when needed. It holds mask registers and
 * various status registers for CPUs to check what interrupts are pending as
 * well as facilities to send IPIs to other cpus.
 */

#include <cstring>

#include "arch/sparc/isa_traits.hh"
#include "arch/sparc/faults.hh"
#include "base/trace.hh"
#include "cpu/intr_control.hh"
#include "dev/sparc/iob.hh"
#include "dev/platform.hh"
#include "mem/port.hh"
#include "mem/packet_access.hh"
#include "sim/faults.hh"
#include "sim/system.hh"

Iob::Iob(const Params *p)
    : PioDevice(p), ic(p->platform->intrctrl)
{
    iobManAddr = ULL(0x9800000000);
    iobManSize = ULL(0x0100000000);
    iobJBusAddr = ULL(0x9F00000000);
    iobJBusSize = ULL(0x0100000000);
    assert (params()->system->threadContexts.size() <= MaxNiagaraProcs);

    pioDelay = p->pio_latency;

    // Get the interrupt controller from the platform
    ic = platform->intrctrl;

    for (int x = 0; x < NumDeviceIds; ++x) {
        intMan[x].cpu = 0;
        intMan[x].vector = 0;
        intCtl[x].mask = true;
        intCtl[x].pend = false;
    }

}

Tick
Iob::read(PacketPtr pkt)
{

    if (pkt->getAddr() >= iobManAddr && pkt->getAddr() < iobManAddr + iobManSize)
        readIob(pkt);
    else if (pkt->getAddr() >= iobJBusAddr && pkt->getAddr() < iobJBusAddr+iobJBusSize)
        readJBus(pkt);
    else
        panic("Invalid address reached Iob\n");

    pkt->makeAtomicResponse();
    return pioDelay;
}

void
Iob::readIob(PacketPtr pkt)
{
        Addr accessAddr = pkt->getAddr() - iobManAddr;
        int index;
        uint64_t data;

        if (accessAddr >= IntManAddr && accessAddr < IntManAddr + IntManSize) {
            index = (accessAddr - IntManAddr) >> 3;
            data = intMan[index].cpu << 8 | intMan[index].vector << 0;
            pkt->set(data);
            return;
        }

        if (accessAddr >= IntCtlAddr && accessAddr < IntCtlAddr + IntCtlSize) {
            index = (accessAddr - IntManAddr) >> 3;
            data = intCtl[index].mask  ? 1 << 2 : 0 |
                   intCtl[index].pend  ? 1 << 0 : 0;
            pkt->set(data);
            return;
        }

        if (accessAddr == JIntVecAddr) {
            pkt->set(jIntVec);
            return;
        }

        panic("Read to unknown IOB offset 0x%x\n", accessAddr);
}

void
Iob::readJBus(PacketPtr pkt)
{
        Addr accessAddr = pkt->getAddr() - iobJBusAddr;
        int cpuid = pkt->req->contextId();
        int index;
        uint64_t data;

        if (accessAddr >= JIntData0Addr && accessAddr < JIntData1Addr) {
            index = (accessAddr - JIntData0Addr) >> 3;
            pkt->set(jBusData0[index]);
            return;
        }

        if (accessAddr >= JIntData1Addr && accessAddr < JIntDataA0Addr) {
            index = (accessAddr - JIntData1Addr) >> 3;
            pkt->set(jBusData1[index]);
            return;
        }

        if (accessAddr == JIntDataA0Addr) {
            pkt->set(jBusData0[cpuid]);
            return;
        }

        if (accessAddr == JIntDataA1Addr) {
            pkt->set(jBusData1[cpuid]);
            return;
        }

        if (accessAddr >= JIntBusyAddr && accessAddr < JIntBusyAddr + JIntBusySize) {
            index = (accessAddr - JIntBusyAddr) >> 3;
            data = jIntBusy[index].busy ? 1 << 5 : 0 |
                   jIntBusy[index].source;
            pkt->set(data);
            return;
        }
        if (accessAddr == JIntABusyAddr) {
            data = jIntBusy[cpuid].busy ? 1 << 5 : 0 |
                   jIntBusy[cpuid].source;
            pkt->set(data);
            return;
        };

        panic("Read to unknown JBus offset 0x%x\n", accessAddr);
}

Tick
Iob::write(PacketPtr pkt)
{
    if (pkt->getAddr() >= iobManAddr && pkt->getAddr() < iobManAddr + iobManSize)
        writeIob(pkt);
    else if (pkt->getAddr() >= iobJBusAddr && pkt->getAddr() < iobJBusAddr+iobJBusSize)
        writeJBus(pkt);
    else
        panic("Invalid address reached Iob\n");

    pkt->makeAtomicResponse();
    return pioDelay;
}

void
Iob::writeIob(PacketPtr pkt)
{
        Addr accessAddr = pkt->getAddr() - iobManAddr;
        int index;
        uint64_t data;

        if (accessAddr >= IntManAddr && accessAddr < IntManAddr + IntManSize) {
            index = (accessAddr - IntManAddr) >> 3;
            data = pkt->get<uint64_t>();
            intMan[index].cpu = bits(data,12,8);
            intMan[index].vector = bits(data,5,0);
            DPRINTF(Iob, "Wrote IntMan %d cpu %d, vec %d\n", index,
                    intMan[index].cpu, intMan[index].vector);
            return;
        }

        if (accessAddr >= IntCtlAddr && accessAddr < IntCtlAddr + IntCtlSize) {
            index = (accessAddr - IntManAddr) >> 3;
            data = pkt->get<uint64_t>();
            intCtl[index].mask = bits(data,2,2);
            if (bits(data,1,1))
                intCtl[index].pend = false;
            DPRINTF(Iob, "Wrote IntCtl %d pend %d cleared %d\n", index,
                    intCtl[index].pend, bits(data,2,2));
            return;
        }

        if (accessAddr == JIntVecAddr) {
            jIntVec = bits(pkt->get<uint64_t>(), 5,0);
            DPRINTF(Iob, "Wrote jIntVec %d\n", jIntVec);
            return;
        }

        if (accessAddr >= IntVecDisAddr && accessAddr < IntVecDisAddr + IntVecDisSize) {
            Type type;
            int cpu_id;
            int vector;
            index = (accessAddr - IntManAddr) >> 3;
            data = pkt->get<uint64_t>();
            type = (Type)bits(data,17,16);
            cpu_id = bits(data, 12,8);
            vector = bits(data,5,0);
            generateIpi(type,cpu_id, vector);
            return;
        }

        panic("Write to unknown IOB offset 0x%x\n", accessAddr);
}

void
Iob::writeJBus(PacketPtr pkt)
{
        Addr accessAddr = pkt->getAddr() - iobJBusAddr;
        int cpuid = pkt->req->contextId();
        int index;
        uint64_t data;

        if (accessAddr >= JIntBusyAddr && accessAddr < JIntBusyAddr + JIntBusySize) {
            index = (accessAddr - JIntBusyAddr) >> 3;
            data = pkt->get<uint64_t>();
            jIntBusy[index].busy = bits(data,5,5);
            DPRINTF(Iob, "Wrote jIntBusy index %d busy: %d\n", index,
                    jIntBusy[index].busy);
            return;
        }
        if (accessAddr == JIntABusyAddr) {
            data = pkt->get<uint64_t>();
            jIntBusy[cpuid].busy = bits(data,5,5);
            DPRINTF(Iob, "Wrote jIntBusy index %d busy: %d\n", cpuid,
                    jIntBusy[cpuid].busy);
            return;
        };

        panic("Write to unknown JBus offset 0x%x\n", accessAddr);
}

void
Iob::receiveDeviceInterrupt(DeviceId devid)
{
    assert(devid < NumDeviceIds);
    if (intCtl[devid].mask)
        return;
    intCtl[devid].mask = true;
    intCtl[devid].pend = true;
    DPRINTF(Iob, "Receiving Device interrupt: %d for cpu %d vec %d\n",
            devid, intMan[devid].cpu, intMan[devid].vector);
    ic->post(intMan[devid].cpu, SparcISA::IT_INT_VEC, intMan[devid].vector);
}

void
Iob::generateIpi(Type type, int cpu_id, int vector)
{
    SparcISA::SparcFault<SparcISA::PowerOnReset> *por = new SparcISA::PowerOnReset();
    if (cpu_id >= sys->getNumCPUs())
        return;

    switch (type) {
      case 0: // interrupt
        DPRINTF(Iob, "Generating interrupt because of I/O write to cpu: %d vec %d\n",
                cpu_id, vector);
        ic->post(cpu_id, SparcISA::IT_INT_VEC, vector);
        break;
      case 1: // reset
        warn("Sending reset to CPU: %d\n", cpu_id);
        if (vector != por->trapType())
            panic("Don't know how to set non-POR reset to cpu\n");
        por->invoke(sys->threadContexts[cpu_id]);
        sys->threadContexts[cpu_id]->activate();
        break;
      case 2: // idle -- this means stop executing and don't wake on interrupts
        DPRINTF(Iob, "Idling CPU because of I/O write cpu: %d\n", cpu_id);
        sys->threadContexts[cpu_id]->halt();
        break;
      case 3: // resume
        DPRINTF(Iob, "Resuming CPU because of I/O write cpu: %d\n", cpu_id);
        sys->threadContexts[cpu_id]->activate();
        break;
      default:
        panic("Invalid type to generate ipi\n");
    }
}

bool
Iob::receiveJBusInterrupt(int cpu_id, int source, uint64_t d0, uint64_t d1)
{
    // If we are already dealing with an interrupt for that cpu we can't deal
    // with another one right now... come back later
    if (jIntBusy[cpu_id].busy)
        return false;

    DPRINTF(Iob, "Receiving jBus interrupt: %d for cpu %d vec %d\n",
            source, cpu_id, jIntVec);

    jIntBusy[cpu_id].busy = true;
    jIntBusy[cpu_id].source = source;
    jBusData0[cpu_id] = d0;
    jBusData1[cpu_id] = d1;

    ic->post(cpu_id, SparcISA::IT_INT_VEC, jIntVec);
    return true;
}

void
Iob::addressRanges(AddrRangeList &range_list)
{
    range_list.clear();
    range_list.push_back(RangeSize(iobManAddr, iobManSize));
    range_list.push_back(RangeSize(iobJBusAddr, iobJBusSize));
}

void
Iob::serialize(std::ostream &os)
{

    SERIALIZE_SCALAR(jIntVec);
    SERIALIZE_ARRAY(jBusData0, MaxNiagaraProcs);
    SERIALIZE_ARRAY(jBusData1, MaxNiagaraProcs);
    for (int x = 0; x < NumDeviceIds; x++) {
        nameOut(os, csprintf("%s.Int%d", name(), x));
        paramOut(os, "cpu", intMan[x].cpu);
        paramOut(os, "vector", intMan[x].vector);
        paramOut(os, "mask", intCtl[x].mask);
        paramOut(os, "pend", intCtl[x].pend);
    };
    for (int x = 0; x < MaxNiagaraProcs; x++) {
        nameOut(os, csprintf("%s.jIntBusy%d", name(), x));
        paramOut(os, "busy", jIntBusy[x].busy);
        paramOut(os, "source", jIntBusy[x].source);
    };
}

void
Iob::unserialize(Checkpoint *cp, const std::string &section)
{
    UNSERIALIZE_SCALAR(jIntVec);
    UNSERIALIZE_ARRAY(jBusData0, MaxNiagaraProcs);
    UNSERIALIZE_ARRAY(jBusData1, MaxNiagaraProcs);
    for (int x = 0; x < NumDeviceIds; x++) {
        paramIn(cp, csprintf("%s.Int%d", name(), x), "cpu", intMan[x].cpu);
        paramIn(cp, csprintf("%s.Int%d", name(), x), "vector", intMan[x].vector);
        paramIn(cp, csprintf("%s.Int%d", name(), x), "mask", intCtl[x].mask);
        paramIn(cp, csprintf("%s.Int%d", name(), x), "pend", intCtl[x].pend);
    };
    for (int x = 0; x < MaxNiagaraProcs; x++) {
        paramIn(cp, csprintf("%s.jIntBusy%d", name(), x), "busy", jIntBusy[x].busy);
        paramIn(cp, csprintf("%s.jIntBusy%d", name(), x), "source", jIntBusy[x].source);
    };
}

Iob *
IobParams::create()
{
    return new Iob(this);
}
<commit_msg>Fix SPARC_FS compile<commit_after>/*
 * Copyright (c) 2006 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Ali Saidi
 */

/** @file
 * This device implemetns the niagara I/O bridge chip. It manages incomming
 * interrupts and posts them to the CPU when needed. It holds mask registers and
 * various status registers for CPUs to check what interrupts are pending as
 * well as facilities to send IPIs to other cpus.
 */

#include <cstring>

#include "arch/sparc/isa_traits.hh"
#include "arch/sparc/faults.hh"
#include "base/trace.hh"
#include "cpu/intr_control.hh"
#include "dev/sparc/iob.hh"
#include "dev/platform.hh"
#include "mem/port.hh"
#include "mem/packet_access.hh"
#include "sim/faults.hh"
#include "sim/system.hh"

Iob::Iob(const Params *p)
    : PioDevice(p), ic(p->platform->intrctrl)
{
    iobManAddr = ULL(0x9800000000);
    iobManSize = ULL(0x0100000000);
    iobJBusAddr = ULL(0x9F00000000);
    iobJBusSize = ULL(0x0100000000);
    assert (params()->system->threadContexts.size() <= MaxNiagaraProcs);

    pioDelay = p->pio_latency;

    // Get the interrupt controller from the platform
    ic = platform->intrctrl;

    for (int x = 0; x < NumDeviceIds; ++x) {
        intMan[x].cpu = 0;
        intMan[x].vector = 0;
        intCtl[x].mask = true;
        intCtl[x].pend = false;
    }

}

Tick
Iob::read(PacketPtr pkt)
{

    if (pkt->getAddr() >= iobManAddr && pkt->getAddr() < iobManAddr + iobManSize)
        readIob(pkt);
    else if (pkt->getAddr() >= iobJBusAddr && pkt->getAddr() < iobJBusAddr+iobJBusSize)
        readJBus(pkt);
    else
        panic("Invalid address reached Iob\n");

    pkt->makeAtomicResponse();
    return pioDelay;
}

void
Iob::readIob(PacketPtr pkt)
{
        Addr accessAddr = pkt->getAddr() - iobManAddr;
        int index;
        uint64_t data;

        if (accessAddr >= IntManAddr && accessAddr < IntManAddr + IntManSize) {
            index = (accessAddr - IntManAddr) >> 3;
            data = intMan[index].cpu << 8 | intMan[index].vector << 0;
            pkt->set(data);
            return;
        }

        if (accessAddr >= IntCtlAddr && accessAddr < IntCtlAddr + IntCtlSize) {
            index = (accessAddr - IntManAddr) >> 3;
            data = intCtl[index].mask  ? 1 << 2 : 0 |
                   intCtl[index].pend  ? 1 << 0 : 0;
            pkt->set(data);
            return;
        }

        if (accessAddr == JIntVecAddr) {
            pkt->set(jIntVec);
            return;
        }

        panic("Read to unknown IOB offset 0x%x\n", accessAddr);
}

void
Iob::readJBus(PacketPtr pkt)
{
        Addr accessAddr = pkt->getAddr() - iobJBusAddr;
        int cpuid = pkt->req->contextId();
        int index;
        uint64_t data;

        if (accessAddr >= JIntData0Addr && accessAddr < JIntData1Addr) {
            index = (accessAddr - JIntData0Addr) >> 3;
            pkt->set(jBusData0[index]);
            return;
        }

        if (accessAddr >= JIntData1Addr && accessAddr < JIntDataA0Addr) {
            index = (accessAddr - JIntData1Addr) >> 3;
            pkt->set(jBusData1[index]);
            return;
        }

        if (accessAddr == JIntDataA0Addr) {
            pkt->set(jBusData0[cpuid]);
            return;
        }

        if (accessAddr == JIntDataA1Addr) {
            pkt->set(jBusData1[cpuid]);
            return;
        }

        if (accessAddr >= JIntBusyAddr && accessAddr < JIntBusyAddr + JIntBusySize) {
            index = (accessAddr - JIntBusyAddr) >> 3;
            data = jIntBusy[index].busy ? 1 << 5 : 0 |
                   jIntBusy[index].source;
            pkt->set(data);
            return;
        }
        if (accessAddr == JIntABusyAddr) {
            data = jIntBusy[cpuid].busy ? 1 << 5 : 0 |
                   jIntBusy[cpuid].source;
            pkt->set(data);
            return;
        };

        panic("Read to unknown JBus offset 0x%x\n", accessAddr);
}

Tick
Iob::write(PacketPtr pkt)
{
    if (pkt->getAddr() >= iobManAddr && pkt->getAddr() < iobManAddr + iobManSize)
        writeIob(pkt);
    else if (pkt->getAddr() >= iobJBusAddr && pkt->getAddr() < iobJBusAddr+iobJBusSize)
        writeJBus(pkt);
    else
        panic("Invalid address reached Iob\n");

    pkt->makeAtomicResponse();
    return pioDelay;
}

void
Iob::writeIob(PacketPtr pkt)
{
        Addr accessAddr = pkt->getAddr() - iobManAddr;
        int index;
        uint64_t data;

        if (accessAddr >= IntManAddr && accessAddr < IntManAddr + IntManSize) {
            index = (accessAddr - IntManAddr) >> 3;
            data = pkt->get<uint64_t>();
            intMan[index].cpu = bits(data,12,8);
            intMan[index].vector = bits(data,5,0);
            DPRINTF(Iob, "Wrote IntMan %d cpu %d, vec %d\n", index,
                    intMan[index].cpu, intMan[index].vector);
            return;
        }

        if (accessAddr >= IntCtlAddr && accessAddr < IntCtlAddr + IntCtlSize) {
            index = (accessAddr - IntManAddr) >> 3;
            data = pkt->get<uint64_t>();
            intCtl[index].mask = bits(data,2,2);
            if (bits(data,1,1))
                intCtl[index].pend = false;
            DPRINTF(Iob, "Wrote IntCtl %d pend %d cleared %d\n", index,
                    intCtl[index].pend, bits(data,2,2));
            return;
        }

        if (accessAddr == JIntVecAddr) {
            jIntVec = bits(pkt->get<uint64_t>(), 5,0);
            DPRINTF(Iob, "Wrote jIntVec %d\n", jIntVec);
            return;
        }

        if (accessAddr >= IntVecDisAddr && accessAddr < IntVecDisAddr + IntVecDisSize) {
            Type type;
            int cpu_id;
            int vector;
            index = (accessAddr - IntManAddr) >> 3;
            data = pkt->get<uint64_t>();
            type = (Type)bits(data,17,16);
            cpu_id = bits(data, 12,8);
            vector = bits(data,5,0);
            generateIpi(type,cpu_id, vector);
            return;
        }

        panic("Write to unknown IOB offset 0x%x\n", accessAddr);
}

void
Iob::writeJBus(PacketPtr pkt)
{
        Addr accessAddr = pkt->getAddr() - iobJBusAddr;
        int cpuid = pkt->req->contextId();
        int index;
        uint64_t data;

        if (accessAddr >= JIntBusyAddr && accessAddr < JIntBusyAddr + JIntBusySize) {
            index = (accessAddr - JIntBusyAddr) >> 3;
            data = pkt->get<uint64_t>();
            jIntBusy[index].busy = bits(data,5,5);
            DPRINTF(Iob, "Wrote jIntBusy index %d busy: %d\n", index,
                    jIntBusy[index].busy);
            return;
        }
        if (accessAddr == JIntABusyAddr) {
            data = pkt->get<uint64_t>();
            jIntBusy[cpuid].busy = bits(data,5,5);
            DPRINTF(Iob, "Wrote jIntBusy index %d busy: %d\n", cpuid,
                    jIntBusy[cpuid].busy);
            return;
        };

        panic("Write to unknown JBus offset 0x%x\n", accessAddr);
}

void
Iob::receiveDeviceInterrupt(DeviceId devid)
{
    assert(devid < NumDeviceIds);
    if (intCtl[devid].mask)
        return;
    intCtl[devid].mask = true;
    intCtl[devid].pend = true;
    DPRINTF(Iob, "Receiving Device interrupt: %d for cpu %d vec %d\n",
            devid, intMan[devid].cpu, intMan[devid].vector);
    ic->post(intMan[devid].cpu, SparcISA::IT_INT_VEC, intMan[devid].vector);
}

void
Iob::generateIpi(Type type, int cpu_id, int vector)
{
    SparcISA::SparcFault<SparcISA::PowerOnReset> *por = new SparcISA::PowerOnReset();
    if (cpu_id >= sys->numContexts())
        return;

    switch (type) {
      case 0: // interrupt
        DPRINTF(Iob, "Generating interrupt because of I/O write to cpu: %d vec %d\n",
                cpu_id, vector);
        ic->post(cpu_id, SparcISA::IT_INT_VEC, vector);
        break;
      case 1: // reset
        warn("Sending reset to CPU: %d\n", cpu_id);
        if (vector != por->trapType())
            panic("Don't know how to set non-POR reset to cpu\n");
        por->invoke(sys->threadContexts[cpu_id]);
        sys->threadContexts[cpu_id]->activate();
        break;
      case 2: // idle -- this means stop executing and don't wake on interrupts
        DPRINTF(Iob, "Idling CPU because of I/O write cpu: %d\n", cpu_id);
        sys->threadContexts[cpu_id]->halt();
        break;
      case 3: // resume
        DPRINTF(Iob, "Resuming CPU because of I/O write cpu: %d\n", cpu_id);
        sys->threadContexts[cpu_id]->activate();
        break;
      default:
        panic("Invalid type to generate ipi\n");
    }
}

bool
Iob::receiveJBusInterrupt(int cpu_id, int source, uint64_t d0, uint64_t d1)
{
    // If we are already dealing with an interrupt for that cpu we can't deal
    // with another one right now... come back later
    if (jIntBusy[cpu_id].busy)
        return false;

    DPRINTF(Iob, "Receiving jBus interrupt: %d for cpu %d vec %d\n",
            source, cpu_id, jIntVec);

    jIntBusy[cpu_id].busy = true;
    jIntBusy[cpu_id].source = source;
    jBusData0[cpu_id] = d0;
    jBusData1[cpu_id] = d1;

    ic->post(cpu_id, SparcISA::IT_INT_VEC, jIntVec);
    return true;
}

void
Iob::addressRanges(AddrRangeList &range_list)
{
    range_list.clear();
    range_list.push_back(RangeSize(iobManAddr, iobManSize));
    range_list.push_back(RangeSize(iobJBusAddr, iobJBusSize));
}

void
Iob::serialize(std::ostream &os)
{

    SERIALIZE_SCALAR(jIntVec);
    SERIALIZE_ARRAY(jBusData0, MaxNiagaraProcs);
    SERIALIZE_ARRAY(jBusData1, MaxNiagaraProcs);
    for (int x = 0; x < NumDeviceIds; x++) {
        nameOut(os, csprintf("%s.Int%d", name(), x));
        paramOut(os, "cpu", intMan[x].cpu);
        paramOut(os, "vector", intMan[x].vector);
        paramOut(os, "mask", intCtl[x].mask);
        paramOut(os, "pend", intCtl[x].pend);
    };
    for (int x = 0; x < MaxNiagaraProcs; x++) {
        nameOut(os, csprintf("%s.jIntBusy%d", name(), x));
        paramOut(os, "busy", jIntBusy[x].busy);
        paramOut(os, "source", jIntBusy[x].source);
    };
}

void
Iob::unserialize(Checkpoint *cp, const std::string &section)
{
    UNSERIALIZE_SCALAR(jIntVec);
    UNSERIALIZE_ARRAY(jBusData0, MaxNiagaraProcs);
    UNSERIALIZE_ARRAY(jBusData1, MaxNiagaraProcs);
    for (int x = 0; x < NumDeviceIds; x++) {
        paramIn(cp, csprintf("%s.Int%d", name(), x), "cpu", intMan[x].cpu);
        paramIn(cp, csprintf("%s.Int%d", name(), x), "vector", intMan[x].vector);
        paramIn(cp, csprintf("%s.Int%d", name(), x), "mask", intCtl[x].mask);
        paramIn(cp, csprintf("%s.Int%d", name(), x), "pend", intCtl[x].pend);
    };
    for (int x = 0; x < MaxNiagaraProcs; x++) {
        paramIn(cp, csprintf("%s.jIntBusy%d", name(), x), "busy", jIntBusy[x].busy);
        paramIn(cp, csprintf("%s.jIntBusy%d", name(), x), "source", jIntBusy[x].source);
    };
}

Iob *
IobParams::create()
{
    return new Iob(this);
}
<|endoftext|>


<commit_before>#include "logging.h"
#include "resources.h"
#include "textureManager.h"

TextureManager textureManager;

TextureManager::TextureManager()
{
    defaultRepeated = false;
    defaultSmooth = false;
    autoSprite = true;
    disabled = false;
}

TextureManager::~TextureManager()
{
}

void TextureManager::setTexture(sf::Sprite& sprite, const string& name, unsigned int spriteIndex)
{
    TextureData& data = textureMap[name];
    if (data.texture.getSize().x < 1)
        loadTexture(name, sf::Vector2i(0, 0));

    if (spriteIndex < data.sprites.size())
    {
        sprite.setTexture(data.texture);
        sprite.setTextureRect(data.sprites[spriteIndex]);
        sprite.setOrigin(float(data.sprites[spriteIndex].width) / 2, float(data.sprites[spriteIndex].height) / 2);
    }else{
        sprite.setTexture(data.texture, true);
        sprite.setOrigin(data.texture.getSize().x / 2, data.texture.getSize().y / 2);
    }
}

sf::Texture* TextureManager::getTexture(const string& name, sf::Vector2i subDiv)
{
    if (disabled)
        return nullptr;
    TextureData& data = textureMap[name];
    if (data.texture.getSize().x < 1)
        loadTexture(name, subDiv);
    return &data.texture;
}

const sf::IntRect TextureManager::getSpriteRect(const string& name, unsigned int spriteIndex)
{
    TextureData& data = textureMap[name];
    if (data.texture.getSize().x < 1)
        loadTexture(name, sf::Vector2i(0, 0));

    if (spriteIndex < data.sprites.size())
        return data.sprites[spriteIndex];

    return sf::IntRect(sf::Vector2i(0, 0), sf::Vector2i(data.texture.getSize()));
}

void TextureManager::setSpriteRect(const string& name, unsigned int spriteIndex, const sf::IntRect rect)
{
    TextureData& data = textureMap[name];
    if (data.texture.getSize().x < 1)
        loadTexture(name, sf::Vector2i(0, 0));

    if (spriteIndex < data.sprites.size())
        data.sprites[spriteIndex] = rect;
    else
        data.sprites.push_back(rect);
}

void TextureManager::loadTexture(const string& name, sf::Vector2i subDiv)
{
    TextureData& data = textureMap[name];

    sf::Image tmpImage;
    P<ResourceStream> stream = getResourceStream(name);
    if (!stream) stream = getResourceStream(name + ".png");
    if (!stream || !tmpImage.loadFromStream(**stream))
    {
        LOG(WARNING) << "Failed to load texture: " << name;
        sf::Image image;
        image.create(8, 8, sf::Color(255, 0, 255, 128));
        data.texture.loadFromImage(image);
        return;
    }

    if (subDiv.x > 0 || subDiv.y > 0)
    {
        subDiv.x = std::max(subDiv.x, 1);
        subDiv.y = std::max(subDiv.y, 1);
        int w = tmpImage.getSize().x / subDiv.x;
        int h = tmpImage.getSize().y / subDiv.y;
        for(int y=0; y<subDiv.y; y++)
        {
            for(int x=0; x<subDiv.x; x++)
            {
                data.sprites.push_back(sf::IntRect(x*w, y*h, w, h));
            }
        }
    }else{
        if (autoSprite)
        {
            for(unsigned int y=0; y<tmpImage.getSize().y; y++)
            {
                for(unsigned int x=0; x<tmpImage.getSize().x; x++)
                {
                    if (tmpImage.getPixel(x, y) == sf::Color(255,0,255))
                    {
                        unsigned int x1=x+1;
                        for(; x1<tmpImage.getSize().x; x1++)
                            if (tmpImage.getPixel(x1, y) == sf::Color(255,0,255))
                                break;
                        unsigned int y1=y+1;
                        for(; y1<tmpImage.getSize().y; y1++)
                            if (tmpImage.getPixel(x, y1) == sf::Color(255,0,255))
                                break;
                        if (x1-x > 1 && y1-y > 1 && x1<tmpImage.getSize().x && y1<tmpImage.getSize().y)
                            data.sprites.push_back(sf::IntRect(x+1, y+1, x1-x-1, y1-y-1));
                        x = x1-1;
                    }
                }
            }
        }
    }
    data.texture.setRepeated(defaultRepeated);
    data.texture.setSmooth(defaultSmooth);

    data.texture.loadFromImage(tmpImage);
    LOG(INFO) << "Loaded: " << name << " with " << data.sprites.size() << " sprites";
}
<commit_msg>Update textureManager.cpp (#103)<commit_after>#include "logging.h"
#include "resources.h"
#include "textureManager.h"

TextureManager textureManager;

TextureManager::TextureManager()
{
    defaultRepeated = false;
    defaultSmooth = false;
    autoSprite = true;
    disabled = false;
}

TextureManager::~TextureManager()
{
}

void TextureManager::setTexture(sf::Sprite& sprite, const string& name, unsigned int spriteIndex)
{
    TextureData& data = textureMap[name];
    if (data.texture.getSize().x < 1)
        loadTexture(name, sf::Vector2i(0, 0));

    if (spriteIndex < data.sprites.size())
    {
        sprite.setTexture(data.texture);
        sprite.setTextureRect(data.sprites[spriteIndex]);
        sprite.setOrigin(float(data.sprites[spriteIndex].width) / 2, float(data.sprites[spriteIndex].height) / 2);
    }else{
        sprite.setTexture(data.texture, true);
        sprite.setOrigin(data.texture.getSize().x / 2.f, data.texture.getSize().y / 2.f);
    }
}

sf::Texture* TextureManager::getTexture(const string& name, sf::Vector2i subDiv)
{
    if (disabled)
        return nullptr;
    TextureData& data = textureMap[name];
    if (data.texture.getSize().x < 1)
        loadTexture(name, subDiv);
    return &data.texture;
}

const sf::IntRect TextureManager::getSpriteRect(const string& name, unsigned int spriteIndex)
{
    TextureData& data = textureMap[name];
    if (data.texture.getSize().x < 1)
        loadTexture(name, sf::Vector2i(0, 0));

    if (spriteIndex < data.sprites.size())
        return data.sprites[spriteIndex];

    return sf::IntRect(sf::Vector2i(0, 0), sf::Vector2i(data.texture.getSize()));
}

void TextureManager::setSpriteRect(const string& name, unsigned int spriteIndex, const sf::IntRect rect)
{
    TextureData& data = textureMap[name];
    if (data.texture.getSize().x < 1)
        loadTexture(name, sf::Vector2i(0, 0));

    if (spriteIndex < data.sprites.size())
        data.sprites[spriteIndex] = rect;
    else
        data.sprites.push_back(rect);
}

void TextureManager::loadTexture(const string& name, sf::Vector2i subDiv)
{
    TextureData& data = textureMap[name];

    sf::Image tmpImage;
    P<ResourceStream> stream = getResourceStream(name);
    if (!stream) stream = getResourceStream(name + ".png");
    if (!stream || !tmpImage.loadFromStream(**stream))
    {
        LOG(WARNING) << "Failed to load texture: " << name;
        sf::Image image;
        image.create(8, 8, sf::Color(255, 0, 255, 128));
        data.texture.loadFromImage(image);
        return;
    }

    if (subDiv.x > 0 || subDiv.y > 0)
    {
        subDiv.x = std::max(subDiv.x, 1);
        subDiv.y = std::max(subDiv.y, 1);
        int w = tmpImage.getSize().x / subDiv.x;
        int h = tmpImage.getSize().y / subDiv.y;
        for(int y=0; y<subDiv.y; y++)
        {
            for(int x=0; x<subDiv.x; x++)
            {
                data.sprites.push_back(sf::IntRect(x*w, y*h, w, h));
            }
        }
    }else{
        if (autoSprite)
        {
            for(unsigned int y=0; y<tmpImage.getSize().y; y++)
            {
                for(unsigned int x=0; x<tmpImage.getSize().x; x++)
                {
                    if (tmpImage.getPixel(x, y) == sf::Color(255,0,255))
                    {
                        unsigned int x1=x+1;
                        for(; x1<tmpImage.getSize().x; x1++)
                            if (tmpImage.getPixel(x1, y) == sf::Color(255,0,255))
                                break;
                        unsigned int y1=y+1;
                        for(; y1<tmpImage.getSize().y; y1++)
                            if (tmpImage.getPixel(x, y1) == sf::Color(255,0,255))
                                break;
                        if (x1-x > 1 && y1-y > 1 && x1<tmpImage.getSize().x && y1<tmpImage.getSize().y)
                            data.sprites.push_back(sf::IntRect(x+1, y+1, x1-x-1, y1-y-1));
                        x = x1-1;
                    }
                }
            }
        }
    }
    data.texture.setRepeated(defaultRepeated);
    data.texture.setSmooth(defaultSmooth);

    data.texture.loadFromImage(tmpImage);
    LOG(INFO) << "Loaded: " << name << " with " << data.sprites.size() << " sprites";
}
<|endoftext|>