mirror of
https://gitea.sffempire.ru/Kolyah35/minecraft-pe-0.6.1.git
synced 2026-03-20 15:03:32 +00:00
the whole game
This commit is contained in:
439
src/main_rpi.h
Executable file
439
src/main_rpi.h
Executable file
@@ -0,0 +1,439 @@
|
||||
#ifndef MAIN_RPI_H__
|
||||
#define MAIN_RPI_H__
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include "bcm_host.h"
|
||||
|
||||
//#include "GLES/gl.h"
|
||||
#include "EGL/egl.h"
|
||||
#include "EGL/eglext.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <png.h>
|
||||
|
||||
#include <SDL/SDL.h>
|
||||
|
||||
#define check() assert(glGetError() == 0)
|
||||
|
||||
#include "App.h"
|
||||
#include "platform/input/Mouse.h"
|
||||
#include "platform/input/Multitouch.h"
|
||||
#include "platform/input/Keyboard.h"
|
||||
|
||||
int width = 848;
|
||||
int height = 480;
|
||||
|
||||
static void png_funcReadFile(png_structp pngPtr, png_bytep data, png_size_t length) {
|
||||
((std::istream*)png_get_io_ptr(pngPtr))->read((char*)data, length);
|
||||
}
|
||||
|
||||
class AppPlatform_linux: public AppPlatform
|
||||
{
|
||||
public:
|
||||
bool isTouchscreen() { return false; }
|
||||
|
||||
TextureData loadTexture(const std::string& filename_, bool textureFolder)
|
||||
{
|
||||
TextureData out;
|
||||
|
||||
std::string filename = textureFolder? "data/images/" + filename_
|
||||
: filename_;
|
||||
std::ifstream source(filename.c_str(), std::ios::binary);
|
||||
|
||||
if (source) {
|
||||
png_structp pngPtr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
|
||||
if (!pngPtr)
|
||||
return out;
|
||||
|
||||
png_infop infoPtr = png_create_info_struct(pngPtr);
|
||||
|
||||
if (!infoPtr) {
|
||||
png_destroy_read_struct(&pngPtr, NULL, NULL);
|
||||
return out;
|
||||
}
|
||||
|
||||
// Hack to get around the broken libpng for windows
|
||||
png_set_read_fn(pngPtr,(voidp)&source, png_funcReadFile);
|
||||
|
||||
png_read_info(pngPtr, infoPtr);
|
||||
|
||||
// Set up the texdata properties
|
||||
out.w = png_get_image_width(pngPtr, infoPtr);
|
||||
out.h = png_get_image_height(pngPtr, infoPtr);
|
||||
|
||||
png_bytep* rowPtrs = new png_bytep[out.h];
|
||||
out.data = new unsigned char[4 * out.w * out.h];
|
||||
out.memoryHandledExternally = false;
|
||||
|
||||
int rowStrideBytes = 4 * out.w;
|
||||
for (int i = 0; i < out.h; i++) {
|
||||
rowPtrs[i] = (png_bytep)&out.data[i*rowStrideBytes];
|
||||
}
|
||||
png_read_image(pngPtr, rowPtrs);
|
||||
|
||||
// Teardown and return
|
||||
png_destroy_read_struct(&pngPtr, &infoPtr,(png_infopp)0);
|
||||
delete[] (png_bytep)rowPtrs;
|
||||
source.close();
|
||||
|
||||
return out;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGI("Couldn't find file: %s\n", filename.c_str());
|
||||
return out;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static bool _inited_egl = false;
|
||||
static bool _app_inited = false;
|
||||
static int _app_window_normal = true;
|
||||
|
||||
static void move_surface(App* app, AppContext* state, uint32_t x, uint32_t y, uint32_t w, uint32_t h);
|
||||
|
||||
static void initEgl(App* app, AppContext* state, uint32_t w, uint32_t h)
|
||||
{
|
||||
move_surface(app, state, 16, 16, w, h);
|
||||
}
|
||||
|
||||
static void deinitEgl(AppContext* state) {
|
||||
//printf("deinitEgl: (inited: %d)\n", _inited_egl);
|
||||
if (!_inited_egl) {
|
||||
return;
|
||||
}
|
||||
|
||||
eglSwapBuffers(state->display, state->surface);
|
||||
eglMakeCurrent(state->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
eglDestroySurface(state->display, state->surface);
|
||||
eglDestroySurface(state->display, state->context);
|
||||
eglTerminate(state->display);
|
||||
|
||||
//state->doRender = false;
|
||||
_inited_egl = false;
|
||||
}
|
||||
|
||||
void move_surface(App* app, AppContext* state, uint32_t x, uint32_t y, uint32_t w, uint32_t h) {
|
||||
int32_t success = 0;
|
||||
EGLBoolean result;
|
||||
EGLint num_config;
|
||||
|
||||
deinitEgl(state);
|
||||
//printf("initEgl\n");
|
||||
|
||||
static EGL_DISPMANX_WINDOW_T nativewindow;
|
||||
|
||||
DISPMANX_ELEMENT_HANDLE_T dispman_element;
|
||||
DISPMANX_DISPLAY_HANDLE_T dispman_display;
|
||||
DISPMANX_UPDATE_HANDLE_T dispman_update;
|
||||
VC_RECT_T dst_rect;
|
||||
VC_RECT_T src_rect;
|
||||
|
||||
static const EGLint attribute_list[] =
|
||||
{
|
||||
EGL_RED_SIZE, 8,
|
||||
EGL_GREEN_SIZE, 8,
|
||||
EGL_BLUE_SIZE, 8,
|
||||
EGL_ALPHA_SIZE, 8,
|
||||
EGL_DEPTH_SIZE, 16,
|
||||
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
|
||||
EGL_NONE
|
||||
};
|
||||
|
||||
static const EGLint context_attributes[] =
|
||||
{
|
||||
EGL_CONTEXT_CLIENT_VERSION, 1,
|
||||
EGL_NONE
|
||||
};
|
||||
EGLConfig config;
|
||||
|
||||
// get an EGL display connection
|
||||
state->display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
assert(state->display!=EGL_NO_DISPLAY);
|
||||
check();
|
||||
|
||||
// initialize the EGL display connection
|
||||
result = eglInitialize(state->display, NULL, NULL);
|
||||
assert(EGL_FALSE != result);
|
||||
check();
|
||||
|
||||
// get an appropriate EGL frame buffer configuration
|
||||
result = eglChooseConfig(state->display, attribute_list, &config, 1, &num_config);
|
||||
assert(EGL_FALSE != result);
|
||||
check();
|
||||
|
||||
// get an appropriate EGL frame buffer configuration
|
||||
result = eglBindAPI(EGL_OPENGL_ES_API);
|
||||
assert(EGL_FALSE != result);
|
||||
check();
|
||||
|
||||
// create an EGL rendering context
|
||||
state->context = eglCreateContext(state->display, config, EGL_NO_CONTEXT, context_attributes);
|
||||
assert(state->context!=EGL_NO_CONTEXT);
|
||||
check();
|
||||
|
||||
// create an EGL window surface
|
||||
uint32_t dw, dh;
|
||||
success = graphics_get_display_size(0 /* LCD */, &dw, &dh);
|
||||
assert( success >= 0 );
|
||||
|
||||
dst_rect.x = x;
|
||||
dst_rect.y = y;
|
||||
dst_rect.width = w;
|
||||
dst_rect.height = h;
|
||||
|
||||
src_rect.x = 0;
|
||||
src_rect.y = 0;
|
||||
src_rect.width = w << 16;
|
||||
src_rect.height = h << 16;
|
||||
|
||||
dispman_display = vc_dispmanx_display_open( 0 /* LCD */);
|
||||
dispman_update = vc_dispmanx_update_start( 0 );
|
||||
|
||||
dispman_element = vc_dispmanx_element_add ( dispman_update, dispman_display,
|
||||
0/*layer*/, &dst_rect, 0/*src*/,
|
||||
&src_rect, DISPMANX_PROTECTION_NONE, 0 /*alpha*/, 0/*clamp*/, (DISPMANX_TRANSFORM_T)0/*transform*/);
|
||||
|
||||
nativewindow.element = dispman_element;
|
||||
nativewindow.width = w;//state->screen_width;
|
||||
nativewindow.height = h;//state->screen_height;
|
||||
vc_dispmanx_update_submit_sync( dispman_update );
|
||||
|
||||
check();
|
||||
|
||||
state->surface = eglCreateWindowSurface( state->display, config, &nativewindow, NULL );
|
||||
assert(state->surface != EGL_NO_SURFACE);
|
||||
check();
|
||||
|
||||
// connect the context to the surface
|
||||
result = eglMakeCurrent(state->display, state->surface, state->surface, state->context);
|
||||
assert(EGL_FALSE != result);
|
||||
check();
|
||||
|
||||
_inited_egl = true;
|
||||
|
||||
if (!_app_inited) {
|
||||
_app_inited = true;
|
||||
app->init(*state);
|
||||
} else {
|
||||
app->onGraphicsReset(*state);
|
||||
}
|
||||
app->setSize(w, h);
|
||||
}
|
||||
|
||||
void teardown() {
|
||||
SDL_Quit();
|
||||
bcm_host_deinit();
|
||||
}
|
||||
|
||||
/*
|
||||
static bool isGrabbed = false;
|
||||
static void setGrabbed(bool status) {
|
||||
SDL_WM_GrabInput(status? SDL_GRAB_ON : SDL_GRAB_OFF);
|
||||
SDL_ShowCursor (status? 0 : 1);
|
||||
isGrabbed = status;
|
||||
printf("set grabbed: %d\n", isGrabbed);
|
||||
}
|
||||
*/
|
||||
|
||||
static unsigned char transformKey(int key) {
|
||||
// Handle ALL keys here. If not handled -> return 0 ("invalid")
|
||||
if (key == SDLK_LSHIFT) return Keyboard::KEY_LSHIFT;
|
||||
if (key == SDLK_DOWN) return 40;
|
||||
if (key == SDLK_UP) return 38;
|
||||
if (key == SDLK_SPACE) return Keyboard::KEY_SPACE;
|
||||
if (key == SDLK_RETURN) return 13;//Keyboard::KEY_RETURN;
|
||||
if (key == SDLK_ESCAPE) return Keyboard::KEY_ESCAPE;
|
||||
if (key == SDLK_TAB) return 250;
|
||||
if (key >= 'a' && key <= 'z') return key - 32;
|
||||
if (key >= SDLK_0 && key <= SDLK_9) return '0' + (key - SDLK_0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int handleEvents() {
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event)) {
|
||||
if (SDL_QUIT == event.type) {
|
||||
return -1;
|
||||
}
|
||||
if (SDL_KEYDOWN == event.type) {
|
||||
int key = event.key.keysym.sym;
|
||||
unsigned char transformed = transformKey(key);
|
||||
/*
|
||||
if (SDLK_ESCAPE == key) {
|
||||
if (SDL_GRAB_ON == SDL_WM_GrabInput(SDL_GRAB_QUERY)) {
|
||||
setGrabbed(false);
|
||||
}
|
||||
}
|
||||
*/
|
||||
//printf("KeyDown: %d => %d\n", key, transformed);
|
||||
if (transformed) Keyboard::feed(transformed, 1);
|
||||
}
|
||||
if (SDL_KEYUP == event.type) {
|
||||
int key = event.key.keysym.sym;
|
||||
unsigned char transformed = transformKey(key);
|
||||
if (transformed) Keyboard::feed(transformed, 0);
|
||||
}
|
||||
if (SDL_MOUSEBUTTONDOWN == event.type) {
|
||||
if (SDL_BUTTON_WHEELUP == event.button.button) {
|
||||
Mouse::feed(3, 0, event.button.x, event.button.y, 0, 1);
|
||||
} else
|
||||
if (SDL_BUTTON_WHEELDOWN == event.button.button) {
|
||||
Mouse::feed(3, 0, event.button.x, event.button.y, 0, -1);
|
||||
} else {
|
||||
bool left = SDL_BUTTON_LEFT == event.button.button;
|
||||
char button = left? 1 : 2;
|
||||
Mouse::feed(button, 1, event.button.x, event.button.y);
|
||||
Multitouch::feed(button, 1, event.button.x, event.button.y, 0);
|
||||
|
||||
//if (!isGrabbed) setGrabbed(true);
|
||||
}
|
||||
}
|
||||
if (SDL_MOUSEBUTTONUP == event.type) {
|
||||
bool left = SDL_BUTTON_LEFT == event.button.button;
|
||||
char button = left? 1 : 2;//MouseAction::ACTION_LEFT : MouseAction::ACTION_RIGHT;
|
||||
Mouse::feed(button, 0, event.button.x, event.button.y);
|
||||
Multitouch::feed(button, 0, event.button.x, event.button.y, 0);
|
||||
|
||||
//if (!isGrabbed) setGrabbed(true);
|
||||
}
|
||||
if (SDL_MOUSEMOTION == event.type) {
|
||||
//printf("mouse: %d, %d\n", event.motion.xrel, event.motion.yrel);
|
||||
float x = event.motion.x;
|
||||
float y = event.motion.y;
|
||||
Multitouch::feed(0, 0, x, y, 0);
|
||||
|
||||
if (1 /*|| isGrabbed*/) {
|
||||
Mouse::feed(0, 0, x, y, event.motion.xrel, event.motion.yrel);
|
||||
} else {
|
||||
Mouse::feed(0, 0, x, y, 0, 0);
|
||||
}
|
||||
}
|
||||
if (SDL_ACTIVEEVENT == event.type) {
|
||||
if (SDL_APPACTIVE & event.active.state) _app_window_normal = event.active.gain;
|
||||
//printf("state: %d (%d), %d, %d, %d\n", event.active.state, event.active.gain, SDL_APPACTIVE, SDL_APPMOUSEFOCUS, SDL_APPINPUTFOCUS);
|
||||
}
|
||||
/*
|
||||
if (SDL_VIDEORESIZE == event.type) {
|
||||
width = event.resize.w;
|
||||
height = event.resize.h;
|
||||
}
|
||||
*/
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void getWindowPosition(int* x, int* y, int* w, int* h);
|
||||
|
||||
void updateWindowPosition(App* app, AppContext* state) {
|
||||
static int lx = -999, ly = -999;
|
||||
static int lw = -999, lh = -999;
|
||||
static int resetTicks = 0;
|
||||
static bool lastWindowNormal = true;
|
||||
static bool allowCreate = true;
|
||||
int x, y;
|
||||
getWindowPosition(&x, &y, &width, &height);
|
||||
|
||||
if (x != lx || y != ly || width != lw || height != lh) {
|
||||
lx = x;
|
||||
ly = y;
|
||||
lw = width;
|
||||
lh = height;
|
||||
resetTicks = 8;
|
||||
deinitEgl(state);
|
||||
//printf("move surface! (%d)\n", _inited_egl );
|
||||
}
|
||||
if (--resetTicks == 0 && allowCreate) {
|
||||
move_surface(app, state, x, y, width, height);
|
||||
}
|
||||
|
||||
if (lastWindowNormal != _app_window_normal) {
|
||||
lastWindowNormal = _app_window_normal;
|
||||
allowCreate = lastWindowNormal;
|
||||
//printf("lastWindowNormal: %d\n", lastWindowNormal);
|
||||
|
||||
if (lastWindowNormal) {
|
||||
//printf("x, y, width, height: %d, %d, %d, %d\n", x, y, width, height);
|
||||
move_surface(app, state, x, y, width, height);
|
||||
//resetTicks = 8;
|
||||
} else {
|
||||
deinitEgl(state);
|
||||
lx = ly = -10000;
|
||||
}
|
||||
// move_surface(app, state, 0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
bcm_host_init();
|
||||
|
||||
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
|
||||
printf("Couldn't initialize SDL\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
SDL_Surface* sdlSurface = SDL_SetVideoMode(width,height,32,SDL_SWSURFACE|SDL_RESIZABLE);
|
||||
if (sdlSurface == NULL) {
|
||||
printf("Couldn't create SDL window\n");
|
||||
return -2;
|
||||
}
|
||||
|
||||
//printf("argv[0]: %s\n", argv[0]);
|
||||
|
||||
std::string path = argv[0];
|
||||
int e = path.rfind('/');
|
||||
if (e != std::string::npos) {
|
||||
path = path.substr(0, e);
|
||||
chdir(path.c_str());
|
||||
}
|
||||
|
||||
char buf[1024];
|
||||
getcwd(buf, 1000);
|
||||
//printf("getcwd: %s\n", buf);
|
||||
|
||||
//printf("HOME: %s\n", getenv("HOME"));
|
||||
|
||||
atexit(teardown);
|
||||
SDL_WM_SetCaption("Minecraft - Pi edition", 0);
|
||||
//setGrabbed(false);;
|
||||
|
||||
MAIN_CLASS* app = new MAIN_CLASS();
|
||||
std::string storagePath = getenv("HOME");
|
||||
storagePath += "/.minecraft/";
|
||||
app->externalStoragePath = storagePath;
|
||||
app->externalCacheStoragePath = storagePath;
|
||||
|
||||
int commandPort = 0;
|
||||
if (argc > 1) {
|
||||
commandPort = atoi(argv[1]);
|
||||
}
|
||||
|
||||
if (commandPort != 0)
|
||||
app->commandPort = commandPort;
|
||||
|
||||
//printf("storage: %s\n", app->externalStoragePath.c_str());
|
||||
|
||||
AppContext context;
|
||||
AppPlatform_linux platform;
|
||||
context.doRender = true;
|
||||
context.platform = &platform;
|
||||
|
||||
initEgl(app, &context, width, height);
|
||||
|
||||
bool running = true;
|
||||
while (running) {
|
||||
|
||||
updateWindowPosition(app, &context);
|
||||
|
||||
running = handleEvents() == 0;
|
||||
app->update();
|
||||
}
|
||||
|
||||
deinitEgl(&context);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user