OpenGL cursor (for non-Windows)
This was SVN commit r817.
This commit is contained in:
parent
48d0bdff97
commit
c8514b7d28
149
source/lib/res/cursor.cpp
Executable file
149
source/lib/res/cursor.cpp
Executable file
@ -0,0 +1,149 @@
|
||||
#include "precompiled.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
// From win.cpp (so we don't need all the Windows headers in here)
|
||||
void cursor_set(const char* name);
|
||||
|
||||
void cursor_draw(const char* name)
|
||||
{
|
||||
cursor_set(name);
|
||||
}
|
||||
|
||||
#else // #ifdef _WIN32
|
||||
|
||||
#include "lib/res/tex.h"
|
||||
#include "lib/res/ogl_tex.h"
|
||||
#include "lib/res/vfs.h"
|
||||
#include "lib/ogl.h"
|
||||
|
||||
extern int mouse_x, mouse_y;
|
||||
|
||||
struct Cursor {
|
||||
Handle tex;
|
||||
int hotspotx, hotspoty;
|
||||
int w, h;
|
||||
void draw(int x, int y)
|
||||
{
|
||||
tex_bind(tex);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glEnable(GL_BLEND);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2i(0, 0); glVertex2i( x-hotspotx, y+hotspoty );
|
||||
glTexCoord2i(1, 0); glVertex2i( x-hotspotx+w, y+hotspoty );
|
||||
glTexCoord2i(1, 1); glVertex2i( x-hotspotx+w, y+hotspoty-h );
|
||||
glTexCoord2i(0, 1); glVertex2i( x-hotspotx, y+hotspoty-h );
|
||||
glEnd();
|
||||
}
|
||||
};
|
||||
|
||||
extern int g_yres;
|
||||
|
||||
// TODO: Remove duplication with Windows cursor code, handle errors, rewrite.
|
||||
void cursor_draw(const char* name)
|
||||
{
|
||||
static struct Cursor* last_cursor = NULL;
|
||||
static char* last_name = NULL;
|
||||
|
||||
if (name == NULL)
|
||||
{
|
||||
// Clean up
|
||||
|
||||
if (last_cursor)
|
||||
{
|
||||
tex_free(last_cursor->tex);
|
||||
delete last_cursor;
|
||||
}
|
||||
last_cursor = NULL;
|
||||
|
||||
delete[] last_name;
|
||||
last_name = NULL;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't do much if it's the same as last time
|
||||
if (last_name && !strcmp(name, last_name))
|
||||
{
|
||||
last_cursor->draw(mouse_x, g_yres-mouse_y);
|
||||
return;
|
||||
}
|
||||
|
||||
// Store the name, so that the code can tell when it's
|
||||
// being called several times with the same cursor
|
||||
delete[] last_name;
|
||||
last_name = new char[strlen(name)+1];
|
||||
strcpy(last_name, name);
|
||||
|
||||
char filename[VFS_MAX_PATH];
|
||||
|
||||
// Load the .txt file containing the pixel offset of
|
||||
// the cursor's hotspot (the bit of it that's
|
||||
// drawn at (mouse_x,mouse_y) )
|
||||
sprintf(filename, "art/textures/cursors/%s.txt", name);
|
||||
|
||||
int hotspotx, hotspoty;
|
||||
{
|
||||
void* data;
|
||||
size_t size;
|
||||
Handle h = vfs_load(filename, data, size);
|
||||
if (h <= 0)
|
||||
{
|
||||
// TODO: Handle errors
|
||||
assert(! "Error loading cursor hotspot .txt file");
|
||||
return;
|
||||
}
|
||||
if (sscanf((const char*)data, "%d %d", &hotspotx, &hotspoty) != 2)
|
||||
{
|
||||
// TODO: Handle errors
|
||||
assert(! "Invalid contents of cursor hotspot .txt file (should be like \"123 456\")");
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Unload the file
|
||||
}
|
||||
|
||||
sprintf(filename, "art/textures/cursors/%s.png", name);
|
||||
|
||||
Handle tex = tex_load(filename);
|
||||
if (tex <= 0)
|
||||
{
|
||||
// TODO: Handle errors
|
||||
assert(! "Error loading cursor texture");
|
||||
return;
|
||||
}
|
||||
|
||||
int err = tex_upload(tex);
|
||||
if (err < 0)
|
||||
{
|
||||
// TODO: Handle errors
|
||||
assert(! "Error uploading cursor texture");
|
||||
return;
|
||||
}
|
||||
|
||||
// Create the cursor object:
|
||||
|
||||
int w, h;
|
||||
tex_info(tex, &w, &h, NULL, NULL, NULL);
|
||||
|
||||
struct Cursor* cursor = new struct Cursor;
|
||||
cursor->tex = tex;
|
||||
cursor->hotspotx = hotspotx;
|
||||
cursor->hotspoty = hotspoty;
|
||||
cursor->w = w;
|
||||
cursor->h = h;
|
||||
|
||||
if (last_cursor)
|
||||
{
|
||||
tex_free(last_cursor->tex);
|
||||
delete last_cursor;
|
||||
}
|
||||
cursor->draw(mouse_x, mouse_y);
|
||||
last_cursor = cursor;
|
||||
}
|
||||
|
||||
#endif // #ifdef _WIN32 / #else
|
1
source/lib/res/cursor.h
Executable file
1
source/lib/res/cursor.h
Executable file
@ -0,0 +1 @@
|
||||
void cursor_draw(const char* name);
|
@ -41,16 +41,8 @@ void check_heap()
|
||||
}
|
||||
|
||||
|
||||
void cursor_set(const char* name)
|
||||
{
|
||||
// TODO: Do a boring OpenGL cursor. Or find a way to
|
||||
// use nice X cursors, because limiting mouse motion to the
|
||||
// OpenGL framerate is a rather horrible thing to do.
|
||||
}
|
||||
|
||||
#endif // #ifndef _WIN32
|
||||
|
||||
|
||||
void debug_break()
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
|
@ -46,11 +46,6 @@ void debug_microlog(const wchar_t *fmt, ...);
|
||||
|
||||
extern void check_heap();
|
||||
|
||||
// Probably only a temporary solution, since it needs to allow an
|
||||
// OpenGL fallback where pretty 32-bit cursors aren't supported
|
||||
// by the OS.
|
||||
extern void cursor_set(const char* filename);
|
||||
|
||||
extern int clipboard_set(const wchar_t* text);
|
||||
extern wchar_t* clipboard_get();
|
||||
extern int clipboard_free(wchar_t* copy);
|
||||
|
@ -17,6 +17,7 @@
|
||||
#ifdef _M_IX86
|
||||
#include "sysdep/ia32.h" // _control87
|
||||
#endif
|
||||
#include "lib/res/cursor.h"
|
||||
|
||||
#include "ps/CConsole.h"
|
||||
|
||||
@ -528,6 +529,9 @@ static void Render()
|
||||
g_Mouseover.renderOverlays();
|
||||
g_Selection.renderOverlays();
|
||||
|
||||
// Draw the cursor (or set the Windows cursor, on Windows)
|
||||
cursor_draw("test");
|
||||
|
||||
// restore
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
@ -546,6 +550,7 @@ static void Render()
|
||||
|
||||
void UpdateWorld(float time)
|
||||
{
|
||||
g_GUI.TickObjects();
|
||||
g_Scheduler.update();
|
||||
simulationTime += (size_t)( time * 1000.0f );
|
||||
frameCount++;
|
||||
@ -730,6 +735,9 @@ static void psShutdown()
|
||||
|
||||
delete g_Console;
|
||||
|
||||
// disable the special Windows cursor, or free textures for OGL cursors
|
||||
cursor_draw(NULL);
|
||||
|
||||
// close down Xerces if it was loaded
|
||||
CXeromyces::Terminate();
|
||||
}
|
||||
@ -763,8 +771,6 @@ static void Shutdown()
|
||||
delete &g_Renderer;
|
||||
|
||||
delete &g_ConfigDB;
|
||||
|
||||
cursor_set(NULL);
|
||||
}
|
||||
|
||||
static void Init(int argc, char* argv[])
|
||||
@ -1029,8 +1035,6 @@ static void Frame()
|
||||
{
|
||||
MICROLOG(L"In frame");
|
||||
|
||||
cursor_set("test");
|
||||
|
||||
#if defined(MOVIE_RECORD) || defined(MOVIE_CREATE)
|
||||
|
||||
// Run at precisely 30fps
|
||||
|
Loading…
Reference in New Issue
Block a user