ANDROID: Support swipe-based virtcontrols
Touching and holding the left side of the screen functions as a joystick. Swiping the middle side allows fine control over arrow keys (eg. dialogues), tapping it sends an enter key. Swiping the right side up/down sends pageup/pagedown.
This commit is contained in:
parent
dcfade91e9
commit
471e4748b3
11 changed files with 243 additions and 119 deletions
|
@ -150,7 +150,9 @@ OSystem_Android::OSystem_Android(int audio_sample_rate, int audio_buffer_size) :
|
|||
_touchpad_scale(66),
|
||||
_dpad_scale(4),
|
||||
_fingersDown(0),
|
||||
_trackball_scale(2) {
|
||||
_trackball_scale(2),
|
||||
_joystickPressing(Common::KEYCODE_INVALID),
|
||||
_arrows_texture(0) {
|
||||
|
||||
_fsFactory = new POSIXFilesystemFactory();
|
||||
|
||||
|
@ -180,8 +182,6 @@ OSystem_Android::OSystem_Android(int audio_sample_rate, int audio_buffer_size) :
|
|||
|
||||
for (int i = 0; i < 4; ++i)
|
||||
_activePointers[i] = -1;
|
||||
|
||||
_joystickPressing = Common::KEYCODE_INVALID;
|
||||
}
|
||||
|
||||
OSystem_Android::~OSystem_Android() {
|
||||
|
@ -194,6 +194,11 @@ OSystem_Android::~OSystem_Android() {
|
|||
delete _timerManager;
|
||||
_timerManager = 0;
|
||||
|
||||
if (_arrows_texture) {
|
||||
delete _arrows_texture;
|
||||
_arrows_texture = 0;
|
||||
}
|
||||
|
||||
deleteMutex(_event_queue_lock);
|
||||
}
|
||||
|
||||
|
|
|
@ -252,18 +252,10 @@ private:
|
|||
kTouchAreaCenter = 0xfffe,
|
||||
kTouchAreaRight = 0xfffd,
|
||||
kTouchAreaNone = 0xfffc,
|
||||
|
||||
};
|
||||
|
||||
uint16 getTouchArea(int x, int y);
|
||||
|
||||
struct VirtControl {
|
||||
int x, y;
|
||||
bool sticky;
|
||||
Common::KeyCode keyCode;
|
||||
bool active;
|
||||
};
|
||||
|
||||
struct Pointer {
|
||||
uint16 startX, startY;
|
||||
uint16 currentX, currentY;
|
||||
|
@ -271,16 +263,27 @@ private:
|
|||
bool active;
|
||||
};
|
||||
|
||||
struct CardinalSwipe {
|
||||
CardinalSwipe(int dX, int dY);
|
||||
uint16 distance;
|
||||
enum Direction {
|
||||
kDirectionLeft,
|
||||
kDirectionUp,
|
||||
kDirectionRight,
|
||||
kDirectionDown
|
||||
} direction;
|
||||
};
|
||||
|
||||
enum { kNumPointers = 5 };
|
||||
static int _virt_numControls;
|
||||
static VirtControl _virtcontrols[];
|
||||
int _virt_numDivisions;
|
||||
Pointer _pointers[kNumPointers];
|
||||
int _activePointers[4];
|
||||
Common::KeyCode _joystickPressing;
|
||||
int &pointerFor(TouchArea ta);
|
||||
const Common::Rect clipFor(const CardinalSwipe &cs);
|
||||
|
||||
void initVirtControls();
|
||||
void drawVirtControls();
|
||||
GLESTexture *_arrows_texture;
|
||||
|
||||
protected:
|
||||
// PaletteManager API
|
||||
|
|
|
@ -23,6 +23,7 @@ PATH_DIST = $(srcdir)/dists/android
|
|||
PATH_RESOURCES = $(PATH_DIST)/res
|
||||
|
||||
PORT_DISTFILES = $(PATH_DIST)/README.Android
|
||||
DIST_ANDROID_CONTROLS = $(PATH_DIST)/assets/arrows.tga
|
||||
|
||||
RESOURCES = \
|
||||
$(PATH_RESOURCES)/values/strings.xml \
|
||||
|
@ -121,9 +122,9 @@ $(PATH_STAGE_PREFIX).%/res/drawable/residualvm.png: $(PATH_RESOURCES)/drawable/r
|
|||
@$(MKDIR) -p $(@D)
|
||||
$(CP) $< $@
|
||||
|
||||
$(FILE_RESOURCES_MAIN): $(FILE_MANIFEST) $(RESOURCES) $(ANDROID_JAR) $(DIST_FILES_THEMES) $(DIST_FILES_ENGINEDATA)
|
||||
$(FILE_RESOURCES_MAIN): $(FILE_MANIFEST) $(RESOURCES) $(ANDROID_JAR) $(DIST_FILES_THEMES) $(DIST_FILES_ENGINEDATA) $(DIST_ANDROID_CONTROLS)
|
||||
$(INSTALL) -d $(PATH_BUILD_ASSETS)
|
||||
$(INSTALL) -c -m 644 $(DIST_FILES_THEMES) $(DIST_FILES_ENGINEDATA) $(PATH_BUILD_ASSETS)/
|
||||
$(INSTALL) -c -m 644 $(DIST_FILES_THEMES) $(DIST_FILES_ENGINEDATA) $(DIST_ANDROID_CONTROLS) $(PATH_BUILD_ASSETS)/
|
||||
work_dir=`pwd`; \
|
||||
for i in $(PATH_BUILD_ASSETS)/*.zip; do \
|
||||
echo "recompress $$i"; \
|
||||
|
|
|
@ -235,6 +235,25 @@ static Common::KeyCode determineKey(int dX, int dY) {
|
|||
return Common::KEYCODE_INVALID;
|
||||
}
|
||||
|
||||
OSystem_Android::CardinalSwipe::CardinalSwipe(int dX, int dY) {
|
||||
if (abs(dX) > abs(dY)) {
|
||||
if (dX > 0) {
|
||||
distance = dX;
|
||||
direction = kDirectionRight;
|
||||
} else {
|
||||
distance = abs(dX);
|
||||
direction = kDirectionLeft;
|
||||
}
|
||||
} else {
|
||||
if (dY > 0) {
|
||||
distance = dY;
|
||||
direction = kDirectionDown;
|
||||
} else {
|
||||
distance = abs(dY);
|
||||
direction = kDirectionUp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const int kQueuedInputEventDelay = 50;
|
||||
|
||||
|
@ -328,28 +347,7 @@ void OSystem_Android::updateEventScale() {
|
|||
_eventScaleX = 100 * 640 / tex->width();
|
||||
}
|
||||
|
||||
int OSystem_Android::_virt_numControls = 6;
|
||||
OSystem_Android::VirtControl OSystem_Android::_virtcontrols[] = {
|
||||
{-2, 1, false, Common::KEYCODE_u, false},
|
||||
{-3, 1, false, Common::KEYCODE_p, false},
|
||||
{-1, 5, false, Common::KEYCODE_i, false},
|
||||
{-1, 0, false, Common::KEYCODE_PAGEDOWN, false},
|
||||
{-1, 1, false, Common::KEYCODE_KP_ENTER, false},
|
||||
{-1, 2, false, Common::KEYCODE_PAGEUP, false},
|
||||
};
|
||||
|
||||
|
||||
uint16 OSystem_Android::getTouchArea(int x, int y) {
|
||||
int scaledX = _virt_numDivisions * x / _egl_surface_width;
|
||||
int scaledY = _virt_numDivisions * (_egl_surface_height - y) / _egl_surface_height;
|
||||
for (uint16 i = 0; i < _virt_numControls; ++i) {
|
||||
int testX = _virtcontrols[i].x < 0
|
||||
? (_virtcontrols[i].x + _virt_numDivisions)
|
||||
: _virtcontrols[i].x;
|
||||
if (scaledX == testX && scaledY == _virtcontrols[i].y)
|
||||
return i;
|
||||
}
|
||||
|
||||
float xPercent = float(x) / _egl_surface_width;
|
||||
|
||||
if (xPercent < 0.3)
|
||||
|
@ -707,8 +705,6 @@ void OSystem_Android::pushEvent(int type, int arg1, int arg2, int arg3,
|
|||
if (idx == kTouchAreaCenter) {
|
||||
e.kbd.keycode = Common::KEYCODE_RETURN;
|
||||
e.kbd.ascii = Common::ASCII_RETURN;
|
||||
} else {
|
||||
e.kbd.keycode = _virtcontrols[idx].keyCode;
|
||||
}
|
||||
|
||||
lockMutex(_event_queue_lock);
|
||||
|
@ -813,9 +809,6 @@ void OSystem_Android::pushEvent(int type, int arg1, int arg2, int arg3,
|
|||
_pointers[arg1].startX = _pointers[arg1].currentX = arg3;
|
||||
_pointers[arg1].startY = _pointers[arg1].currentY = arg4;
|
||||
}
|
||||
|
||||
if (touchArea == kTouchAreaJoystick)
|
||||
LOGW("Started joystick move at (%d,%d)", arg3, arg4);
|
||||
}
|
||||
return;
|
||||
|
||||
|
@ -839,7 +832,6 @@ void OSystem_Android::pushEvent(int type, int arg1, int arg2, int arg3,
|
|||
|
||||
_joystickPressing = newPressing;
|
||||
}
|
||||
LOGW("Joystick moved to (%d,%d)", arg3, arg4);
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
@ -880,34 +872,36 @@ void OSystem_Android::pushEvent(int type, int arg1, int arg2, int arg3,
|
|||
|
||||
unlockMutex(_event_queue_lock);
|
||||
} else {
|
||||
_pointers[arg1].active = false;
|
||||
int dX = _pointers[arg1].currentX - _pointers[arg1].startX;
|
||||
int dY = _pointers[arg1].currentY - _pointers[arg1].startY;
|
||||
struct CardinalSwipe cs(dX, dY);
|
||||
|
||||
switch (_pointers[arg1].function) {
|
||||
case kTouchAreaCenter: {
|
||||
pointerFor(kTouchAreaCenter) = -1;
|
||||
if (abs(dX) < 100 && abs(dY) < 100) {
|
||||
sendKey(Common::KEYCODE_u);
|
||||
} else if (abs(dX) > abs(dY)) {
|
||||
if (dX > 0) {
|
||||
sendKey(Common::KEYCODE_RIGHT);
|
||||
} else {
|
||||
if (cs.distance < 100) {
|
||||
sendKey(Common::KEYCODE_RETURN);
|
||||
break;
|
||||
}
|
||||
switch (cs.direction) {
|
||||
case CardinalSwipe::kDirectionLeft:
|
||||
sendKey(Common::KEYCODE_LEFT);
|
||||
}
|
||||
} else {
|
||||
if (dY > 0) {
|
||||
sendKey(Common::KEYCODE_DOWN);
|
||||
} else {
|
||||
break;
|
||||
case CardinalSwipe::kDirectionUp:
|
||||
sendKey(Common::KEYCODE_UP);
|
||||
}
|
||||
break;
|
||||
case CardinalSwipe::kDirectionRight:
|
||||
sendKey(Common::KEYCODE_RIGHT);
|
||||
break;
|
||||
case CardinalSwipe::kDirectionDown:
|
||||
sendKey(Common::KEYCODE_DOWN);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case kTouchAreaJoystick:
|
||||
pointerFor(kTouchAreaJoystick) = -1;
|
||||
LOGW("Joystick move ended at (%d,%d)", arg3, arg4);
|
||||
if (_joystickPressing != Common::KEYCODE_INVALID) {
|
||||
lockMutex(_event_queue_lock);
|
||||
e.kbd.keycode = _joystickPressing;
|
||||
|
@ -919,13 +913,15 @@ void OSystem_Android::pushEvent(int type, int arg1, int arg2, int arg3,
|
|||
|
||||
case kTouchAreaRight:
|
||||
pointerFor(kTouchAreaRight) = -1;
|
||||
if (abs(dX) > 50 || abs(dY) < 100) {
|
||||
if ( cs.direction == CardinalSwipe::kDirectionLeft
|
||||
|| cs.direction == CardinalSwipe::kDirectionRight
|
||||
|| cs.distance < 100) {
|
||||
sendKey(Common::KEYCODE_i);
|
||||
} else {
|
||||
if (dY > 0) {
|
||||
sendKey(Common::KEYCODE_PAGEDOWN);
|
||||
} else {
|
||||
if (cs.direction == CardinalSwipe::kDirectionUp) {
|
||||
sendKey(Common::KEYCODE_PAGEUP);
|
||||
} else {
|
||||
sendKey(Common::KEYCODE_PAGEDOWN);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -934,6 +930,7 @@ void OSystem_Android::pushEvent(int type, int arg1, int arg2, int arg3,
|
|||
default:
|
||||
break;
|
||||
}
|
||||
_pointers[arg1].active = false;
|
||||
_pointers[arg1].function = kTouchAreaNone;
|
||||
}
|
||||
return;
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
|
||||
#include "common/endian.h"
|
||||
#include "graphics/conversion.h"
|
||||
#include "graphics/decoders/tga.h"
|
||||
#include "graphics/opengles2/shader.h"
|
||||
|
||||
#include "backends/platform/android/android.h"
|
||||
|
@ -569,57 +570,82 @@ void OSystem_Android::updateScreen() {
|
|||
|
||||
}
|
||||
|
||||
static Graphics::Shader *_virtcontrols_shader = NULL;
|
||||
static const char *_virtVertex =
|
||||
"#version 100\n"
|
||||
"attribute vec2 position;\n"
|
||||
"uniform vec2 offsetXY;\n"
|
||||
"uniform vec2 sizeWH;\n"
|
||||
"void main() {\n"
|
||||
"vec2 pos = offsetXY + position * sizeWH;\n"
|
||||
"pos.x = pos.x * 2.0 - 1.0;\n"
|
||||
"pos.y = pos.y * 2.0 - 1.0;\n"
|
||||
"gl_Position = vec4(pos, 0.0, 1.0);\n"
|
||||
"}\n";
|
||||
static GLES8888Texture *loadBuiltinTexture(const char *filename) {
|
||||
Common::ArchiveMemberPtr member = SearchMan.getMember(filename);
|
||||
Common::SeekableReadStream *str = member->createReadStream();
|
||||
Graphics::TGADecoder dec;
|
||||
dec.loadStream(*str);
|
||||
void *pixels = dec.getSurface()->pixels;
|
||||
|
||||
static const char *_virtFragment =
|
||||
"#version 100\n"
|
||||
"precision mediump float;\n"
|
||||
"uniform bool active;\n"
|
||||
"void main() {\n"
|
||||
"gl_FragColor = vec4(1.0, 1.0, 1.0, active ? 0.8 : 0.3);\n"
|
||||
"}\n";
|
||||
GLES8888Texture *ret = new GLES8888Texture();
|
||||
uint16 w = dec.getSurface()->w;
|
||||
uint16 h = dec.getSurface()->h;
|
||||
uint16 pitch = dec.getSurface()->pitch;
|
||||
ret->allocBuffer(w, h);
|
||||
ret->updateBuffer(0, 0, w, h, pixels, pitch);
|
||||
|
||||
delete str;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void OSystem_Android::initVirtControls() {
|
||||
if (_virtcontrols_shader)
|
||||
return;
|
||||
if (!_arrows_texture)
|
||||
_arrows_texture = loadBuiltinTexture("arrows.tga");
|
||||
}
|
||||
|
||||
const char* attributes[] = { "position", NULL };
|
||||
_virtcontrols_shader = Graphics::Shader::fromStrings("key", _virtVertex, _virtFragment, attributes);
|
||||
_virtcontrols_shader->enableVertexAttribute("position", g_verticesVBO, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), 0);
|
||||
_virt_numDivisions = _egl_surface_width > 800 ? 12 : 8;
|
||||
const Common::Rect OSystem_Android::clipFor(const CardinalSwipe &cs) {
|
||||
switch (cs.direction) {
|
||||
case CardinalSwipe::kDirectionLeft:
|
||||
return Common::Rect(0, 128, 128, 256);
|
||||
case CardinalSwipe::kDirectionUp:
|
||||
return Common::Rect(0, 0, 128, 128);
|
||||
case CardinalSwipe::kDirectionRight:
|
||||
return Common::Rect(128, 128, 256, 256);
|
||||
case CardinalSwipe::kDirectionDown:
|
||||
return Common::Rect(128, 0, 256, 128);
|
||||
default: // unreachable
|
||||
return Common::Rect(0, 0, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void OSystem_Android::drawVirtControls() {
|
||||
if (_show_overlay)
|
||||
return;
|
||||
_virtcontrols_shader->use();
|
||||
float div = 1.0 / _virt_numDivisions;
|
||||
float divX = div;
|
||||
float divY = div;
|
||||
_virtcontrols_shader->setUniform("sizeWH", 0.9 * Math::Vector2d(divX, divY));
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
int joyPtr = pointerFor(kTouchAreaJoystick);
|
||||
if (joyPtr != -1) {
|
||||
Pointer &joy = _pointers[joyPtr];
|
||||
CardinalSwipe cs(joy.currentX - joy.startX, joy.currentY - joy.startY);
|
||||
|
||||
for (int control = 0; control < _virt_numControls; ++control) {
|
||||
float offsetX = (_virtcontrols[control].x + 0.1) * divX;
|
||||
float offsetY = (_virtcontrols[control].y + 0.1) * divY;
|
||||
if (offsetX < 0)
|
||||
offsetX += 1.0;
|
||||
if (cs.distance >= 50) {
|
||||
Common::Rect clip = clipFor(cs);
|
||||
_arrows_texture->drawTexture(2 * _egl_surface_width / 10, _egl_surface_height / 2, 64, 64, clip);
|
||||
}
|
||||
}
|
||||
|
||||
_virtcontrols_shader->setUniform("offsetXY", Math::Vector2d(offsetX, offsetY));
|
||||
_virtcontrols_shader->setUniform("active", _virtcontrols[control].active);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
int centerPtr = pointerFor(kTouchAreaCenter);
|
||||
if (centerPtr != -1) {
|
||||
Pointer ¢er = _pointers[centerPtr];
|
||||
CardinalSwipe cs(center.currentX - center.startX, center.currentY - center.startY);
|
||||
|
||||
if (cs.distance >= 100) {
|
||||
Common::Rect clip = clipFor(cs);
|
||||
_arrows_texture->drawTexture(_egl_surface_width / 2, _egl_surface_height / 2, 64, 64, clip);
|
||||
}
|
||||
}
|
||||
|
||||
int rightPtr = pointerFor(kTouchAreaRight);
|
||||
if (rightPtr != -1) {
|
||||
Pointer &right = _pointers[rightPtr];
|
||||
CardinalSwipe cs(right.currentX - right.startX, right.currentY - right.startY);
|
||||
|
||||
if (cs.distance >= 100) {
|
||||
if ( cs.direction == CardinalSwipe::kDirectionDown
|
||||
|| cs.direction == CardinalSwipe::kDirectionUp) {
|
||||
Common::Rect clip = clipFor(cs);
|
||||
_arrows_texture->drawTexture( 8 * _egl_surface_width / 10, _egl_surface_height / 2, 64, 64, clip);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -97,7 +97,7 @@ void GLESBaseTexture::initGL() {
|
|||
}
|
||||
|
||||
const char* attributes[] = { "position", "texcoord", NULL };
|
||||
g_box_shader = Graphics::Shader::fromStrings("box", Graphics::BuiltinShaders::boxVertex, Graphics::BuiltinShaders::boxFragment, attributes);
|
||||
g_box_shader = Graphics::Shader::fromStrings("control", Graphics::BuiltinShaders::controlVertex, Graphics::BuiltinShaders::controlFragment, attributes);
|
||||
g_verticesVBO = Graphics::Shader::createBuffer(GL_ARRAY_BUFFER, sizeof(vertices), vertices);
|
||||
g_box_shader->enableVertexAttribute("position", g_verticesVBO, 2, GL_FLOAT, GL_TRUE, 2 * sizeof(float), 0);
|
||||
g_box_shader->enableVertexAttribute("texcoord", g_verticesVBO, 2, GL_FLOAT, GL_TRUE, 2 * sizeof(float), 0);
|
||||
|
@ -186,7 +186,7 @@ void GLESBaseTexture::allocBuffer(GLuint w, GLuint h) {
|
|||
initSize();
|
||||
}
|
||||
|
||||
void GLESBaseTexture::drawTexture(GLshort x, GLshort y, GLshort w, GLshort h) {
|
||||
void GLESBaseTexture::drawTexture(GLshort x, GLshort y, GLshort w, GLshort h, const Common::Rect &clip) {
|
||||
// LOGD("*** Texture %p: Drawing %dx%d rect to (%d,%d)", this, w, h, x, y);
|
||||
|
||||
assert(g_box_shader);
|
||||
|
@ -197,13 +197,14 @@ void GLESBaseTexture::drawTexture(GLshort x, GLshort y, GLshort w, GLshort h) {
|
|||
const GLfloat offsetY = float(y) / float(JNI::egl_surface_height);
|
||||
const GLfloat sizeW = float(w) / float(JNI::egl_surface_width);
|
||||
const GLfloat sizeH = float(h) / float(JNI::egl_surface_height);
|
||||
const GLfloat tex_width = float(_surface.w) / float(_texture_width);
|
||||
const GLfloat tex_height = float(_surface.h) / float(_texture_height);
|
||||
Math::Vector4d clipV = Math::Vector4d(clip.left, clip.top, clip.right, clip.bottom);
|
||||
clipV.x() /= _texture_width; clipV.y() /= _texture_height;
|
||||
clipV.z() /= _texture_width; clipV.w() /= _texture_height;
|
||||
// LOGD("*** Drawing at (%f,%f) , size %f x %f", float(x) / float(_surface.w), float(y) / float(_surface.h), tex_width, tex_height);
|
||||
|
||||
g_box_shader->setUniform("offsetXY", Math::Vector2d(offsetX, offsetY));
|
||||
g_box_shader->setUniform("sizeWH", Math::Vector2d(sizeW, sizeH));
|
||||
g_box_shader->setUniform("texcrop", Math::Vector2d(tex_width, tex_height));
|
||||
g_box_shader->setUniform("clip", clipV);
|
||||
g_box_shader->setUniform("flipY", !_is_game_texture);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
@ -281,7 +282,7 @@ void GLESTexture::fillBuffer(uint32 color) {
|
|||
setDirty();
|
||||
}
|
||||
|
||||
void GLESTexture::drawTexture(GLshort x, GLshort y, GLshort w, GLshort h) {
|
||||
void GLESTexture::drawTexture(GLshort x, GLshort y, GLshort w, GLshort h, const Common::Rect &clip) {
|
||||
if (_all_dirty) {
|
||||
_dirty_rect.top = 0;
|
||||
_dirty_rect.left = 0;
|
||||
|
@ -323,7 +324,7 @@ void GLESTexture::drawTexture(GLshort x, GLshort y, GLshort w, GLshort h) {
|
|||
dwidth, dheight, _glFormat, _glType, _tex));
|
||||
}
|
||||
|
||||
GLESBaseTexture::drawTexture(x, y, w, h);
|
||||
GLESBaseTexture::drawTexture(x, y, w, h, clip);
|
||||
}
|
||||
|
||||
GLES4444Texture::GLES4444Texture() :
|
||||
|
@ -333,6 +334,13 @@ GLES4444Texture::GLES4444Texture() :
|
|||
GLES4444Texture::~GLES4444Texture() {
|
||||
}
|
||||
|
||||
GLES8888Texture::GLES8888Texture() :
|
||||
GLESTexture(GL_RGBA, GL_UNSIGNED_BYTE, pixelFormat()) {
|
||||
}
|
||||
|
||||
GLES8888Texture::~GLES8888Texture() {
|
||||
}
|
||||
|
||||
GLES5551Texture::GLES5551Texture() :
|
||||
GLESTexture(GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, pixelFormat()) {
|
||||
}
|
||||
|
@ -419,8 +427,7 @@ void GLESFakePaletteTexture::updateBuffer(GLuint x, GLuint y, GLuint w,
|
|||
} while (--h);
|
||||
}
|
||||
|
||||
void GLESFakePaletteTexture::drawTexture(GLshort x, GLshort y, GLshort w,
|
||||
GLshort h) {
|
||||
void GLESFakePaletteTexture::drawTexture(GLshort x, GLshort y, GLshort w, GLshort h, const Common::Rect &clip) {
|
||||
if (_all_dirty) {
|
||||
_dirty_rect.top = 0;
|
||||
_dirty_rect.left = 0;
|
||||
|
@ -452,7 +459,7 @@ void GLESFakePaletteTexture::drawTexture(GLshort x, GLshort y, GLshort w,
|
|||
dwidth, dheight, _glFormat, _glType, _buf));
|
||||
}
|
||||
|
||||
GLESBaseTexture::drawTexture(x, y, w, h);
|
||||
GLESBaseTexture::drawTexture(x, y, w, h, clip);
|
||||
}
|
||||
|
||||
const Graphics::PixelFormat &GLESFakePaletteTexture::getPixelFormat() const {
|
||||
|
|
|
@ -57,7 +57,11 @@ public:
|
|||
const void *buf, int pitch_buf) = 0;
|
||||
virtual void fillBuffer(uint32 color) = 0;
|
||||
|
||||
virtual void drawTexture(GLshort x, GLshort y, GLshort w, GLshort h);
|
||||
virtual void drawTexture(GLshort x, GLshort y, GLshort w, GLshort h) {
|
||||
drawTexture(x, y, w, h, Common::Rect(0, 0, width(), height()));
|
||||
}
|
||||
virtual void drawTexture(GLshort x, GLshort y, GLshort w, GLshort h, const Common::Rect &clip);
|
||||
|
||||
|
||||
inline void setDrawRect(const Common::Rect &rect) {
|
||||
_draw_rect = rect;
|
||||
|
@ -203,13 +207,26 @@ public:
|
|||
const void *buf, int pitch_buf);
|
||||
virtual void fillBuffer(uint32 color);
|
||||
|
||||
virtual void drawTexture(GLshort x, GLshort y, GLshort w, GLshort h);
|
||||
virtual void drawTexture(GLshort x, GLshort y, GLshort w, GLshort h) {
|
||||
drawTexture(x, y, w, h, Common::Rect(0, 0, width(), height()));
|
||||
}
|
||||
virtual void drawTexture(GLshort x, GLshort y, GLshort w, GLshort h, const Common::Rect &clip);
|
||||
|
||||
protected:
|
||||
byte *_pixels;
|
||||
byte *_buf;
|
||||
};
|
||||
|
||||
class GLES8888Texture : public GLESTexture {
|
||||
public:
|
||||
GLES8888Texture();
|
||||
virtual ~GLES8888Texture();
|
||||
|
||||
static Graphics::PixelFormat pixelFormat() {
|
||||
return Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
|
||||
}
|
||||
};
|
||||
|
||||
// RGBA4444 texture
|
||||
class GLES4444Texture : public GLESTexture {
|
||||
public:
|
||||
|
@ -256,7 +273,10 @@ public:
|
|||
const void *buf, int pitch_buf);
|
||||
virtual void fillBuffer(uint32 color);
|
||||
|
||||
virtual void drawTexture(GLshort x, GLshort y, GLshort w, GLshort h);
|
||||
virtual void drawTexture(GLshort x, GLshort y, GLshort w, GLshort h) {
|
||||
drawTexture(x, y, w, h, Common::Rect(0, 0, width(), height()));
|
||||
}
|
||||
virtual void drawTexture(GLshort x, GLshort y, GLshort w, GLshort h, const Common::Rect &clip);
|
||||
|
||||
virtual const byte *palette_const() const {
|
||||
return (byte *)_palette;
|
||||
|
|
BIN
dists/android/assets/arrows.tga
Normal file
BIN
dists/android/assets/arrows.tga
Normal file
Binary file not shown.
After Width: | Height: | Size: 256 KiB |
|
@ -23,6 +23,7 @@ MODULE_OBJS := \
|
|||
pixelbuffer.o \
|
||||
opengles2/shader.o \
|
||||
opengles2/box_shaders.o \
|
||||
opengles2/control_shaders.o \
|
||||
opengles2/compat_shaders.o \
|
||||
tinygl/api.o \
|
||||
tinygl/arrays.o \
|
||||
|
|
65
graphics/opengles2/control_shaders.cpp
Normal file
65
graphics/opengles2/control_shaders.cpp
Normal file
|
@ -0,0 +1,65 @@
|
|||
/* ResidualVM - A 3D game interpreter
|
||||
*
|
||||
* ResidualVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/scummsys.h"
|
||||
|
||||
#ifdef USE_GLES2
|
||||
|
||||
namespace Graphics {
|
||||
namespace BuiltinShaders {
|
||||
|
||||
const char *controlVertex =
|
||||
"#version 100\n"
|
||||
"attribute vec2 position;\n"
|
||||
"attribute vec2 texcoord;\n"
|
||||
"uniform vec2 offsetXY;\n"
|
||||
"uniform vec2 sizeWH;\n"
|
||||
"uniform vec4 clip;\n"
|
||||
"uniform bool flipY;\n"
|
||||
"varying vec2 Texcoord;\n"
|
||||
"void main() {\n"
|
||||
"Texcoord = clip.xy + texcoord * (clip.zw - clip.xy);\n"
|
||||
"vec2 pos = offsetXY + position * sizeWH;\n"
|
||||
"pos.x = pos.x * 2.0 - 1.0;\n"
|
||||
"pos.y = pos.y * 2.0 - 1.0;\n"
|
||||
"if (flipY)\n"
|
||||
"pos.y *= -1.0;\n"
|
||||
"gl_Position = vec4(pos, 0.0, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
const char *controlFragment =
|
||||
"#version 100\n"
|
||||
"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
|
||||
"precision highp float;\n"
|
||||
"#else\n"
|
||||
"precision mediump float;\n"
|
||||
"#endif\n"
|
||||
"varying vec2 Texcoord;\n"
|
||||
"uniform sampler2D tex;\n"
|
||||
"void main() {\n"
|
||||
"gl_FragColor = texture2D(tex, Texcoord);\n"
|
||||
"}\n";
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -34,10 +34,9 @@
|
|||
namespace Graphics {
|
||||
|
||||
namespace BuiltinShaders {
|
||||
extern const char *boxVertex;
|
||||
extern const char *boxFragment;
|
||||
extern const char *compatVertex;
|
||||
extern const char *compatFragment;
|
||||
extern const char *boxVertex, *boxFragment;
|
||||
extern const char *compatVertex, *compatFragment;
|
||||
extern const char *controlVertex, *controlFragment;
|
||||
}
|
||||
|
||||
struct VertexAttrib {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue