android port

This commit is contained in:
2026-08-28 21:23:08 +03:00
parent aaf298d8cc
commit eef7d2b046
41 changed files with 1428 additions and 142 deletions
+4
View File
@@ -33,6 +33,10 @@ DECLARE_BUILD_STAGE(engine)
"openxr.cpp",
};
if (ldProject.m_target.kernel == TARGET_KERNEL_ANDROID)
{
compileProject.files.AppendTail("filesystem_android.cpp");
}
if ( GET_PROJECT_VALUE(config, "steam") == "true" )
{
+1 -1
View File
@@ -11,7 +11,7 @@ void CClientGameDLL::Init()
CreateInterfaceFn pfnServerFactory = Sys_GetFactory("client");
IEngineBridge *pEngineBridge = (IEngineBridge*)pfnServerFactory(ENGINE_BRIDGE_INTERFACE_VERSION, NULL);
IEngineBridge *pEngineBridge = (IEngineBridge*)pfnServerFactory(CLIENT_ENGINE_BRIDGE_INTERFACE_VERSION, NULL);
pEngineBridge->ConnectInterface(FILESYSTEM_INTERFACE_VERSION, filesystem);
pEngineBridge->ConnectInterface(RENDER_CONTEXT_INTERFACE_VERSION, m_pRenderContext);
-2
View File
@@ -151,8 +151,6 @@ extern "C" void FunnyMain( int argc, char **argv )
g_pWindowManager->Frame(fDelta);
g_pClientGame->m_pBridge->Frame(fDelta);
g_pRenderContext->Frame(fDelta);
fCurrent = Plat_GetTime();
}
Console()->Execute();
+139
View File
@@ -0,0 +1,139 @@
#include "tier2/ifilesystem.h"
#include "tier1/interface.h"
#include "android/asset_manager.h"
#include "android/android_native_app_glue.h"
class CAndroidFileHandle : public IFileHandle
{
public:
AAsset *m_pFile;
size_t m_nSize;
};
class CAndroidDirectoryHandle: public IDirectoryHandle
{
public:
};
#include "android/log.h"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, "funnygame", __VA_ARGS__)
extern struct android_app *g_android_app;
class CAndroidFileSystem : public IFileSystem
{
public:
virtual void Init() override {
};
virtual void Shutdown() override {};
virtual IFileHandle *Open( const char *szFileName, int eOpCode ) override
{
LOGI("Opening file: %s", szFileName);
FILE *pFile;
CAndroidFileHandle *pHandle = NULL;
switch (eOpCode)
{
case FILEMODE_READ:
break;
default:
return 0;
}
pHandle = new CAndroidFileHandle;
pHandle->m_pFileSystem = this;
pHandle->m_pFile = AAssetManager_open(g_android_app->activity->assetManager, szFileName, AASSET_MODE_RANDOM);
LOGI("Opened file: %p", pHandle->m_pFile);
pHandle->m_nSize = AAsset_getLength64(pHandle->m_pFile);
return pHandle;
}
virtual size_t Write( IFileHandle *pFile, const void *pData, size_t nDataSize ) override
{
}
virtual size_t Read( IFileHandle *pFile, void *pData, size_t nDataSize ) override
{
CAndroidFileHandle *pHandle = (CAndroidFileHandle*)pFile;
if (!pHandle)
return 0;
return AAsset_read(pHandle->m_pFile, pData, nDataSize);
}
virtual size_t Seek( IFileHandle *pFile, ESeekMode eSeekMode, size_t nOffset ) override
{
CAndroidFileHandle *pHandle = (CAndroidFileHandle*)pFile;
int eLibcSeekMode = 0;
if (!pHandle)
return 0;
switch (eSeekMode) {
case SEEKMODE_RELATIVE_CURRENT:
eLibcSeekMode = SEEK_CUR;
break;
case SEEKMODE_RELATIVE_END:
eLibcSeekMode = SEEK_END;
break;
case SEEKMODE_RELATIVE_START:
eLibcSeekMode = SEEK_SET;
break;
}
return AAsset_seek64(pHandle->m_pFile, nOffset, eLibcSeekMode);
}
virtual size_t Tell( IFileHandle *pFile ) override
{
CAndroidFileHandle *pHandle = (CAndroidFileHandle*)pFile;
if (!pHandle)
return 0;
return AAsset_seek64(pHandle->m_pFile, 0, SEEK_CUR);
}
virtual size_t Size( IFileHandle *pFile ) override
{
CAndroidFileHandle *pHandle = (CAndroidFileHandle*)pFile;
if (!pHandle)
return 0;
return pHandle->m_nSize;
}
virtual void Close( IFileHandle *pFile ) override
{
CAndroidFileHandle *pHandle = (CAndroidFileHandle*)pFile;
if (!pHandle)
return;
AAsset_close(pHandle->m_pFile);
delete pHandle;
}
virtual CUtlBuffer<unsigned char> Read( IFileHandle *pFile ) override { return {}; };
virtual const char *ReadString( IFileHandle *pFile ) override {
char *szData = NULL;
size_t uSize = Size(pFile);
szData = (char*)V_malloc(uSize+1);
Read(pFile, szData,uSize);
szData[uSize] = 0;
return szData;
};
virtual size_t PrintF( IFileHandle *pFile, const char *szFormat, ... ) override
{
return 0;
}
virtual IDirectoryHandle *OpenDir( const char *szDirName ) override
{
return NULL;
};
virtual void CloseDir( IDirectoryHandle *pDir ) override
{
};
};
EXPOSE_INTERFACE(CAndroidFileSystem, IFileSystem, FILESYSTEM_INTERFACE_VERSION)
+1 -2
View File
@@ -7,10 +7,9 @@
void CServerGameDLL::Init()
{
CreateInterfaceFn pfnServerFactory = Sys_GetFactory("server");
IEngineBridge *pEngineBridge = (IEngineBridge*)pfnServerFactory(ENGINE_BRIDGE_INTERFACE_VERSION, NULL);
IEngineBridge *pEngineBridge = (IEngineBridge*)pfnServerFactory(SERVER_ENGINE_BRIDGE_INTERFACE_VERSION, NULL);
pEngineBridge->ConnectInterface(FILESYSTEM_INTERFACE_VERSION, filesystem);
pEngineBridge->ConnectInterface("EngineConstants", m_pEngineConsts);
pEngineBridge->ConnectInterface(FILESYSTEM_INTERFACE_VERSION, filesystem);
pEngineBridge->Init();
m_pBridge = pEngineBridge;
}
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
+457
View File
@@ -0,0 +1,457 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "android_native_app_glue.h"
#include <jni.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <android/log.h>
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "threaded_app", __VA_ARGS__))
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "threaded_app", __VA_ARGS__))
/* For debug builds, always enable the debug traces in this library */
#ifndef NDEBUG
# define LOGV(...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, "threaded_app", __VA_ARGS__))
#else
# define LOGV(...) ((void)0)
#endif
static void free_saved_state(struct android_app* android_app) {
pthread_mutex_lock(&android_app->mutex);
if (android_app->savedState != NULL) {
free(android_app->savedState);
android_app->savedState = NULL;
android_app->savedStateSize = 0;
}
pthread_mutex_unlock(&android_app->mutex);
}
int8_t android_app_read_cmd(struct android_app* android_app) {
int8_t cmd;
if (read(android_app->msgread, &cmd, sizeof(cmd)) != sizeof(cmd)) {
LOGE("No data on command pipe!");
return -1;
}
if (cmd == APP_CMD_SAVE_STATE) free_saved_state(android_app);
return cmd;
}
static void print_cur_config(struct android_app* android_app) {
char lang[2], country[2];
AConfiguration_getLanguage(android_app->config, lang);
AConfiguration_getCountry(android_app->config, country);
LOGV("Config: mcc=%d mnc=%d lang=%c%c cnt=%c%c orien=%d touch=%d dens=%d "
"keys=%d nav=%d keysHid=%d navHid=%d sdk=%d size=%d long=%d "
"modetype=%d modenight=%d",
AConfiguration_getMcc(android_app->config),
AConfiguration_getMnc(android_app->config),
lang[0], lang[1], country[0], country[1],
AConfiguration_getOrientation(android_app->config),
AConfiguration_getTouchscreen(android_app->config),
AConfiguration_getDensity(android_app->config),
AConfiguration_getKeyboard(android_app->config),
AConfiguration_getNavigation(android_app->config),
AConfiguration_getKeysHidden(android_app->config),
AConfiguration_getNavHidden(android_app->config),
AConfiguration_getSdkVersion(android_app->config),
AConfiguration_getScreenSize(android_app->config),
AConfiguration_getScreenLong(android_app->config),
AConfiguration_getUiModeType(android_app->config),
AConfiguration_getUiModeNight(android_app->config));
}
void android_app_pre_exec_cmd(struct android_app* android_app, int8_t cmd) {
switch (cmd) {
case APP_CMD_INPUT_CHANGED:
LOGV("APP_CMD_INPUT_CHANGED");
pthread_mutex_lock(&android_app->mutex);
if (android_app->inputQueue != NULL) {
AInputQueue_detachLooper(android_app->inputQueue);
}
android_app->inputQueue = android_app->pendingInputQueue;
if (android_app->inputQueue != NULL) {
LOGV("Attaching input queue to looper");
AInputQueue_attachLooper(android_app->inputQueue,
android_app->looper, LOOPER_ID_INPUT, NULL,
&android_app->inputPollSource);
}
pthread_cond_broadcast(&android_app->cond);
pthread_mutex_unlock(&android_app->mutex);
break;
case APP_CMD_INIT_WINDOW:
LOGV("APP_CMD_INIT_WINDOW");
pthread_mutex_lock(&android_app->mutex);
android_app->window = android_app->pendingWindow;
pthread_cond_broadcast(&android_app->cond);
pthread_mutex_unlock(&android_app->mutex);
break;
case APP_CMD_TERM_WINDOW:
LOGV("APP_CMD_TERM_WINDOW");
pthread_cond_broadcast(&android_app->cond);
break;
case APP_CMD_RESUME:
case APP_CMD_START:
case APP_CMD_PAUSE:
case APP_CMD_STOP:
LOGV("activityState=%d", cmd);
pthread_mutex_lock(&android_app->mutex);
android_app->activityState = cmd;
pthread_cond_broadcast(&android_app->cond);
pthread_mutex_unlock(&android_app->mutex);
break;
case APP_CMD_CONFIG_CHANGED:
LOGV("APP_CMD_CONFIG_CHANGED");
AConfiguration_fromAssetManager(android_app->config,
android_app->activity->assetManager);
print_cur_config(android_app);
break;
case APP_CMD_DESTROY:
LOGV("APP_CMD_DESTROY");
android_app->destroyRequested = 1;
break;
}
}
void android_app_post_exec_cmd(struct android_app* android_app, int8_t cmd) {
switch (cmd) {
case APP_CMD_TERM_WINDOW:
LOGV("APP_CMD_TERM_WINDOW");
pthread_mutex_lock(&android_app->mutex);
android_app->window = NULL;
pthread_cond_broadcast(&android_app->cond);
pthread_mutex_unlock(&android_app->mutex);
break;
case APP_CMD_SAVE_STATE:
LOGV("APP_CMD_SAVE_STATE");
pthread_mutex_lock(&android_app->mutex);
android_app->stateSaved = 1;
pthread_cond_broadcast(&android_app->cond);
pthread_mutex_unlock(&android_app->mutex);
break;
case APP_CMD_RESUME:
free_saved_state(android_app);
break;
}
}
void app_dummy() {
}
static void android_app_destroy(struct android_app* android_app) {
LOGV("android_app_destroy!");
free_saved_state(android_app);
pthread_mutex_lock(&android_app->mutex);
if (android_app->inputQueue != NULL) {
AInputQueue_detachLooper(android_app->inputQueue);
}
AConfiguration_delete(android_app->config);
android_app->destroyed = 1;
pthread_cond_broadcast(&android_app->cond);
pthread_mutex_unlock(&android_app->mutex);
// Can't touch android_app object after this.
}
static void process_input(struct android_app* app, struct android_poll_source* source) {
AInputEvent* event = NULL;
while (AInputQueue_getEvent(app->inputQueue, &event) >= 0) {
LOGV("New input event: type=%d", AInputEvent_getType(event));
if (AInputQueue_preDispatchEvent(app->inputQueue, event)) {
continue;
}
int32_t handled = 0;
if (app->onInputEvent != NULL) handled = app->onInputEvent(app, event);
AInputQueue_finishEvent(app->inputQueue, event, handled);
}
}
static void process_cmd(struct android_app* app, struct android_poll_source* source) {
int8_t cmd = android_app_read_cmd(app);
android_app_pre_exec_cmd(app, cmd);
if (app->onAppCmd != NULL) app->onAppCmd(app, cmd);
android_app_post_exec_cmd(app, cmd);
}
static void* android_app_entry(void* param) {
struct android_app* android_app = (struct android_app*)param;
android_app->config = AConfiguration_new();
AConfiguration_fromAssetManager(android_app->config, android_app->activity->assetManager);
print_cur_config(android_app);
android_app->cmdPollSource.id = LOOPER_ID_MAIN;
android_app->cmdPollSource.app = android_app;
android_app->cmdPollSource.process = process_cmd;
android_app->inputPollSource.id = LOOPER_ID_INPUT;
android_app->inputPollSource.app = android_app;
android_app->inputPollSource.process = process_input;
ALooper* looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
ALooper_addFd(looper, android_app->msgread, LOOPER_ID_MAIN, ALOOPER_EVENT_INPUT, NULL,
&android_app->cmdPollSource);
android_app->looper = looper;
pthread_mutex_lock(&android_app->mutex);
android_app->running = 1;
pthread_cond_broadcast(&android_app->cond);
pthread_mutex_unlock(&android_app->mutex);
android_main(android_app);
android_app_destroy(android_app);
return NULL;
}
// --------------------------------------------------------------------
// Native activity interaction (called from main thread)
// --------------------------------------------------------------------
static struct android_app* android_app_create(ANativeActivity* activity,
void* savedState, size_t savedStateSize) {
struct android_app* android_app = calloc(1, sizeof(struct android_app));
android_app->activity = activity;
pthread_mutex_init(&android_app->mutex, NULL);
pthread_cond_init(&android_app->cond, NULL);
if (savedState != NULL) {
android_app->savedState = malloc(savedStateSize);
android_app->savedStateSize = savedStateSize;
memcpy(android_app->savedState, savedState, savedStateSize);
}
int msgpipe[2];
if (pipe(msgpipe)) {
LOGE("could not create pipe: %s", strerror(errno));
return NULL;
}
android_app->msgread = msgpipe[0];
android_app->msgwrite = msgpipe[1];
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
pthread_create(&android_app->thread, &attr, android_app_entry, android_app);
// Wait for thread to start.
pthread_mutex_lock(&android_app->mutex);
while (!android_app->running) {
pthread_cond_wait(&android_app->cond, &android_app->mutex);
}
pthread_mutex_unlock(&android_app->mutex);
return android_app;
}
static void android_app_write_cmd(struct android_app* android_app, int8_t cmd) {
if (write(android_app->msgwrite, &cmd, sizeof(cmd)) != sizeof(cmd)) {
LOGE("Failure writing android_app cmd: %s", strerror(errno));
}
}
static void android_app_set_input(struct android_app* android_app, AInputQueue* inputQueue) {
pthread_mutex_lock(&android_app->mutex);
android_app->pendingInputQueue = inputQueue;
android_app_write_cmd(android_app, APP_CMD_INPUT_CHANGED);
while (android_app->inputQueue != android_app->pendingInputQueue) {
pthread_cond_wait(&android_app->cond, &android_app->mutex);
}
pthread_mutex_unlock(&android_app->mutex);
}
static void android_app_set_window(struct android_app* android_app, ANativeWindow* window) {
pthread_mutex_lock(&android_app->mutex);
if (android_app->pendingWindow != NULL) {
android_app_write_cmd(android_app, APP_CMD_TERM_WINDOW);
}
android_app->pendingWindow = window;
if (window != NULL) {
android_app_write_cmd(android_app, APP_CMD_INIT_WINDOW);
}
while (android_app->window != android_app->pendingWindow) {
pthread_cond_wait(&android_app->cond, &android_app->mutex);
}
pthread_mutex_unlock(&android_app->mutex);
}
static void android_app_set_activity_state(struct android_app* android_app, int8_t cmd) {
pthread_mutex_lock(&android_app->mutex);
android_app_write_cmd(android_app, cmd);
while (android_app->activityState != cmd) {
pthread_cond_wait(&android_app->cond, &android_app->mutex);
}
pthread_mutex_unlock(&android_app->mutex);
}
static void android_app_free(struct android_app* android_app) {
pthread_mutex_lock(&android_app->mutex);
android_app_write_cmd(android_app, APP_CMD_DESTROY);
while (!android_app->destroyed) {
pthread_cond_wait(&android_app->cond, &android_app->mutex);
}
pthread_mutex_unlock(&android_app->mutex);
close(android_app->msgread);
close(android_app->msgwrite);
pthread_cond_destroy(&android_app->cond);
pthread_mutex_destroy(&android_app->mutex);
free(android_app);
}
static struct android_app* ToApp(ANativeActivity* activity) {
return (struct android_app*) activity->instance;
}
static void onDestroy(ANativeActivity* activity) {
LOGV("Destroy: %p", activity);
android_app_free(ToApp(activity));
}
static void onStart(ANativeActivity* activity) {
LOGV("Start: %p", activity);
android_app_set_activity_state(ToApp(activity), APP_CMD_START);
}
static void onResume(ANativeActivity* activity) {
LOGV("Resume: %p", activity);
android_app_set_activity_state(ToApp(activity), APP_CMD_RESUME);
}
static void* onSaveInstanceState(ANativeActivity* activity, size_t* outLen) {
LOGV("SaveInstanceState: %p", activity);
struct android_app* android_app = ToApp(activity);
void* savedState = NULL;
pthread_mutex_lock(&android_app->mutex);
android_app->stateSaved = 0;
android_app_write_cmd(android_app, APP_CMD_SAVE_STATE);
while (!android_app->stateSaved) {
pthread_cond_wait(&android_app->cond, &android_app->mutex);
}
if (android_app->savedState != NULL) {
savedState = android_app->savedState;
*outLen = android_app->savedStateSize;
android_app->savedState = NULL;
android_app->savedStateSize = 0;
}
pthread_mutex_unlock(&android_app->mutex);
return savedState;
}
static void onPause(ANativeActivity* activity) {
LOGV("Pause: %p", activity);
android_app_set_activity_state(ToApp(activity), APP_CMD_PAUSE);
}
static void onStop(ANativeActivity* activity) {
LOGV("Stop: %p", activity);
android_app_set_activity_state(ToApp(activity), APP_CMD_STOP);
}
static void onConfigurationChanged(ANativeActivity* activity) {
LOGV("ConfigurationChanged: %p", activity);
android_app_write_cmd(ToApp(activity), APP_CMD_CONFIG_CHANGED);
}
static void onContentRectChanged(ANativeActivity* activity, const ARect* r) {
LOGV("ContentRectChanged: l=%d,t=%d,r=%d,b=%d", r->left, r->top, r->right, r->bottom);
struct android_app* android_app = ToApp(activity);
pthread_mutex_lock(&android_app->mutex);
android_app->contentRect = *r;
pthread_mutex_unlock(&android_app->mutex);
android_app_write_cmd(ToApp(activity), APP_CMD_CONTENT_RECT_CHANGED);
}
static void onLowMemory(ANativeActivity* activity) {
LOGV("LowMemory: %p", activity);
android_app_write_cmd(ToApp(activity), APP_CMD_LOW_MEMORY);
}
static void onWindowFocusChanged(ANativeActivity* activity, int focused) {
LOGV("WindowFocusChanged: %p -- %d", activity, focused);
android_app_write_cmd(ToApp(activity), focused ? APP_CMD_GAINED_FOCUS : APP_CMD_LOST_FOCUS);
}
static void onNativeWindowCreated(ANativeActivity* activity, ANativeWindow* window) {
LOGV("NativeWindowCreated: %p -- %p", activity, window);
android_app_set_window(ToApp(activity), window);
}
static void onNativeWindowDestroyed(ANativeActivity* activity, ANativeWindow* window) {
LOGV("NativeWindowDestroyed: %p -- %p", activity, window);
android_app_set_window(ToApp(activity), NULL);
}
static void onNativeWindowRedrawNeeded(ANativeActivity* activity, ANativeWindow* window) {
LOGV("NativeWindowRedrawNeeded: %p -- %p", activity, window);
android_app_write_cmd(ToApp(activity), APP_CMD_WINDOW_REDRAW_NEEDED);
}
static void onNativeWindowResized(ANativeActivity* activity, ANativeWindow* window) {
LOGV("NativeWindowResized: %p -- %p", activity, window);
android_app_write_cmd(ToApp(activity), APP_CMD_WINDOW_RESIZED);
}
static void onInputQueueCreated(ANativeActivity* activity, AInputQueue* queue) {
LOGV("InputQueueCreated: %p -- %p", activity, queue);
android_app_set_input(ToApp(activity), queue);
}
static void onInputQueueDestroyed(ANativeActivity* activity, AInputQueue* queue) {
LOGV("InputQueueDestroyed: %p -- %p", activity, queue);
android_app_set_input(ToApp(activity), NULL);
}
JNIEXPORT
void ANativeActivity_onCreate(ANativeActivity* activity, void* savedState, size_t savedStateSize) {
LOGV("Creating: %p", activity);
activity->callbacks->onConfigurationChanged = onConfigurationChanged;
activity->callbacks->onContentRectChanged = onContentRectChanged;
activity->callbacks->onDestroy = onDestroy;
activity->callbacks->onInputQueueCreated = onInputQueueCreated;
activity->callbacks->onInputQueueDestroyed = onInputQueueDestroyed;
activity->callbacks->onLowMemory = onLowMemory;
activity->callbacks->onNativeWindowCreated = onNativeWindowCreated;
activity->callbacks->onNativeWindowDestroyed = onNativeWindowDestroyed;
activity->callbacks->onNativeWindowRedrawNeeded = onNativeWindowRedrawNeeded;
activity->callbacks->onNativeWindowResized = onNativeWindowResized;
activity->callbacks->onPause = onPause;
activity->callbacks->onResume = onResume;
activity->callbacks->onSaveInstanceState = onSaveInstanceState;
activity->callbacks->onStart = onStart;
activity->callbacks->onStop = onStop;
activity->callbacks->onWindowFocusChanged = onWindowFocusChanged;
activity->instance = android_app_create(activity, savedState, savedStateSize);
}
+354
View File
@@ -0,0 +1,354 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <poll.h>
#include <pthread.h>
#include <sched.h>
#include <android/configuration.h>
#include <android/looper.h>
#include <android/native_activity.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* The native activity interface provided by <android/native_activity.h>
* is based on a set of application-provided callbacks that will be called
* by the Activity's main thread when certain events occur.
*
* This means that each one of this callbacks _should_ _not_ block, or they
* risk having the system force-close the application. This programming
* model is direct, lightweight, but constraining.
*
* The 'android_native_app_glue' static library is used to provide a different
* execution model where the application can implement its own main event
* loop in a different thread instead. Here's how it works:
*
* 1/ The application must provide a function named "android_main()" that
* will be called when the activity is created (and again every time the
* activity is recreated), in a new thread that is distinct from the
* activity's main thread.
*
* 2/ android_main() receives a pointer to a valid "android_app" structure
* that contains references to other important objects, e.g. the
* ANativeActivity object instance the application is running in.
*
* 3/ the "android_app" object holds an ALooper instance that already
* listens to two important things:
*
* - activity lifecycle events (e.g. "pause", "resume"). See APP_CMD_XXX
* declarations below.
*
* - input events coming from the AInputQueue attached to the activity.
*
* Each of these correspond to an ALooper identifier returned by
* ALooper_pollOnce with values of LOOPER_ID_MAIN and LOOPER_ID_INPUT,
* respectively.
*
* Your application can use the same ALooper to listen to additional
* file-descriptors. They can either be callback based, or with return
* identifiers starting with LOOPER_ID_USER.
*
* 4/ Whenever you receive a LOOPER_ID_MAIN or LOOPER_ID_INPUT event,
* the returned data will point to an android_poll_source structure. You
* can call the process() function on it, and fill in android_app->onAppCmd
* and android_app->onInputEvent to be called for your own processing
* of the event.
*
* Alternatively, you can call the low-level functions to read and process
* the data directly... look at the process_cmd() and process_input()
* implementations in the glue to see how to do this.
*
* See the sample named "native-activity" that comes with the NDK with a
* full usage example. Also look at the JavaDoc of NativeActivity.
*/
struct android_app;
/**
* Data associated with an ALooper fd that will be returned as the "outData"
* when that source has data ready.
*/
struct android_poll_source {
// The identifier of this source. May be LOOPER_ID_MAIN or
// LOOPER_ID_INPUT.
int32_t id;
// The android_app this ident is associated with.
struct android_app* app;
// Function to call to perform the standard processing of data from
// this source.
void (*process)(struct android_app* app, struct android_poll_source* source);
};
/**
* This is the interface for the standard glue code of a threaded
* application. In this model, the application's code is running
* in its own thread separate from the main thread of the process.
* It is not required that this thread be associated with the Java
* VM, although it will need to be in order to make JNI calls any
* Java objects.
*/
struct android_app {
// The application can place a pointer to its own state object
// here if it likes.
void* userData;
// Fill this in with the function to process main app commands (APP_CMD_*)
void (*onAppCmd)(struct android_app* app, int32_t cmd);
// Fill this in with the function to process input events. At this point
// the event has already been pre-dispatched, and it will be finished upon
// return. Return 1 if you have handled the event, 0 for any default
// dispatching.
int32_t (*onInputEvent)(struct android_app* app, AInputEvent* event);
// The ANativeActivity object instance that this app is running in.
ANativeActivity* activity;
// The current configuration the app is running in.
AConfiguration* config;
// This is the last instance's saved state, as provided at creation time.
// It is NULL if there was no state. You can use this as you need; the
// memory will remain around until you call android_app_exec_cmd() for
// APP_CMD_RESUME, at which point it will be freed and savedState set to NULL.
// These variables should only be changed when processing a APP_CMD_SAVE_STATE,
// at which point they will be initialized to NULL and you can malloc your
// state and place the information here. In that case the memory will be
// freed for you later.
void* savedState;
size_t savedStateSize;
// The ALooper associated with the app's thread.
ALooper* looper;
// When non-NULL, this is the input queue from which the app will
// receive user input events.
AInputQueue* inputQueue;
// When non-NULL, this is the window surface that the app can draw in.
ANativeWindow* window;
// Current content rectangle of the window; this is the area where the
// window's content should be placed to be seen by the user.
ARect contentRect;
// Current state of the app's activity. May be either APP_CMD_START,
// APP_CMD_RESUME, APP_CMD_PAUSE, or APP_CMD_STOP; see below.
int activityState;
// This is non-zero when the application's NativeActivity is being
// destroyed and waiting for the app thread to complete.
// Your android_main() must return to its caller when this is non-zero.
int destroyRequested;
// -------------------------------------------------
// Below are "private" implementation of the glue code.
pthread_mutex_t mutex;
pthread_cond_t cond;
int msgread;
int msgwrite;
pthread_t thread;
struct android_poll_source cmdPollSource;
struct android_poll_source inputPollSource;
int running;
int stateSaved;
int destroyed;
int redrawNeeded;
AInputQueue* pendingInputQueue;
ANativeWindow* pendingWindow;
ARect pendingContentRect;
};
enum {
/**
* Looper data ID of commands coming from the app's main thread, which
* is returned as an identifier from ALooper_pollOnce(). The data for this
* identifier is a pointer to an android_poll_source structure.
* These can be retrieved and processed with android_app_read_cmd()
* and android_app_exec_cmd().
*/
LOOPER_ID_MAIN = 1,
/**
* Looper data ID of events coming from the AInputQueue of the
* application's window, which is returned as an identifier from
* ALooper_pollOnce(). The data for this identifier is a pointer to an
* android_poll_source structure. These can be read via the inputQueue
* object of android_app.
*/
LOOPER_ID_INPUT = 2,
/**
* Start of user-defined ALooper identifiers.
*/
LOOPER_ID_USER = 3,
};
enum {
/**
* Command from main thread: the AInputQueue has changed. Upon processing
* this command, android_app->inputQueue will be updated to the new queue
* (or NULL).
*/
APP_CMD_INPUT_CHANGED,
/**
* Command from main thread: a new ANativeWindow is ready for use. Upon
* receiving this command, android_app->window will contain the new window
* surface.
*/
APP_CMD_INIT_WINDOW,
/**
* Command from main thread: the existing ANativeWindow needs to be
* terminated. Upon receiving this command, android_app->window still
* contains the existing window; after calling android_app_exec_cmd
* it will be set to NULL.
*/
APP_CMD_TERM_WINDOW,
/**
* Command from main thread: the current ANativeWindow has been resized.
* Please redraw with its new size.
*/
APP_CMD_WINDOW_RESIZED,
/**
* Command from main thread: the system needs that the current ANativeWindow
* be redrawn. You should redraw the window before handing this to
* android_app_exec_cmd() in order to avoid transient drawing glitches.
*/
APP_CMD_WINDOW_REDRAW_NEEDED,
/**
* Command from main thread: the content area of the window has changed,
* such as from the soft input window being shown or hidden. You can
* find the new content rect in android_app::contentRect.
*/
APP_CMD_CONTENT_RECT_CHANGED,
/**
* Command from main thread: the app's activity window has gained
* input focus.
*/
APP_CMD_GAINED_FOCUS,
/**
* Command from main thread: the app's activity window has lost
* input focus.
*/
APP_CMD_LOST_FOCUS,
/**
* Command from main thread: the current device configuration has changed.
*/
APP_CMD_CONFIG_CHANGED,
/**
* Command from main thread: the system is running low on memory.
* Try to reduce your memory use.
*/
APP_CMD_LOW_MEMORY,
/**
* Command from main thread: the app's activity has been started.
*/
APP_CMD_START,
/**
* Command from main thread: the app's activity has been resumed.
*/
APP_CMD_RESUME,
/**
* Command from main thread: the app should generate a new saved state
* for itself, to restore from later if needed. If you have saved state,
* allocate it with malloc and place it in android_app.savedState with
* the size in android_app.savedStateSize. The will be freed for you
* later.
*/
APP_CMD_SAVE_STATE,
/**
* Command from main thread: the app's activity has been paused.
*/
APP_CMD_PAUSE,
/**
* Command from main thread: the app's activity has been stopped.
*/
APP_CMD_STOP,
/**
* Command from main thread: the app's activity is being destroyed,
* and waiting for the app thread to clean up and exit before proceeding.
*/
APP_CMD_DESTROY,
};
/**
* Call when ALooper_pollAll() returns LOOPER_ID_MAIN, reading the next
* app command message.
*/
int8_t android_app_read_cmd(struct android_app* android_app);
/**
* Call with the command returned by android_app_read_cmd() to do the
* initial pre-processing of the given command. You can perform your own
* actions for the command after calling this function.
*/
void android_app_pre_exec_cmd(struct android_app* android_app, int8_t cmd);
/**
* Call with the command returned by android_app_read_cmd() to do the
* final post-processing of the given command. You must have done your own
* actions for the command before calling this function.
*/
void android_app_post_exec_cmd(struct android_app* android_app, int8_t cmd);
/**
* No-op function that used to be used to prevent the linker from stripping app
* glue code. No longer necessary, since __attribute__((visibility("default")))
* does this for us.
*/
__attribute__((
deprecated("Calls to app_dummy are no longer necessary. See "
"https://github.com/android-ndk/ndk/issues/381."))) void
app_dummy();
/**
* This is the function that application code must implement, representing
* the main entry to the app.
*
* This is called every time the activity is recreated.
*/
extern void android_main(struct android_app* app);
#ifdef __cplusplus
}
#endif
+28 -28
View File
@@ -13,7 +13,7 @@
#define MAX_FONT_COUNT 128
template<typename T, uint32_t nCount>
class CAssetArc
class C_AssetArc
{
struct ObjectHandle_t
{
@@ -76,7 +76,7 @@ public:
}
};
class CAssetManager: public IAssetManager
class C_AssetManager: public IAssetManager
{
public:
virtual HFunnyModel LoadModel( const char *szName ) override;
@@ -105,37 +105,37 @@ public:
void LoadMaterialData( CBaseMaterial *pMaterial, IJSONObject *pObj );
CAssetArc<FunnyModel_t, MAX_MODEL_COUNT> m_models = {};
CAssetArc<FunnyMesh_t, MAX_MESH_COUNT> m_meshes = {};
CAssetArc<FunnyMaterial_t, MAX_MATERIAL_COUNT> m_materials = {};
CAssetArc<FunnyTexture_t, MAX_TEXTURE_COUNT> m_textures = {};
CAssetArc<IShader*, MAX_SHADER_COUNT> m_shaders = {};
CAssetArc<FunnyPhysics_t, MAX_PHYSICS_COUNT> m_physics = {};
C_AssetArc<FunnyModel_t, MAX_MODEL_COUNT> m_models = {};
C_AssetArc<FunnyMesh_t, MAX_MESH_COUNT> m_meshes = {};
C_AssetArc<FunnyMaterial_t, MAX_MATERIAL_COUNT> m_materials = {};
C_AssetArc<FunnyTexture_t, MAX_TEXTURE_COUNT> m_textures = {};
C_AssetArc<IShader*, MAX_SHADER_COUNT> m_shaders = {};
C_AssetArc<FunnyPhysics_t, MAX_PHYSICS_COUNT> m_physics = {};
};
FunnyModel_t *CAssetManager::GetModelByIndex( uint32_t uIndex )
FunnyModel_t *C_AssetManager::GetModelByIndex( uint32_t uIndex )
{
return m_models.GetObjectPtr(uIndex);
}
FunnyMaterial_t *CAssetManager::GetMaterialByIndex( uint32_t uIndex )
FunnyMaterial_t *C_AssetManager::GetMaterialByIndex( uint32_t uIndex )
{
return m_materials.GetObjectPtr(uIndex);
}
IShader **CAssetManager::GetShaderByIndex( uint32_t uIndex )
IShader **C_AssetManager::GetShaderByIndex( uint32_t uIndex )
{
return m_shaders.GetObjectPtr(uIndex);
}
FunnyMesh_t *CAssetManager::GetMeshByIndex( uint32_t uIndex )
FunnyMesh_t *C_AssetManager::GetMeshByIndex( uint32_t uIndex )
{
return m_meshes.GetObjectPtr(uIndex);
}
uint32_t CAssetManager::LoadModel( const char *szName )
uint32_t C_AssetManager::LoadModel( const char *szName )
{
bool bHasBeenCreated = false;
HFunnyModel hModel = m_models.GetOrCreateObject(szName, &bHasBeenCreated);
@@ -189,12 +189,12 @@ uint32_t CAssetManager::LoadModel( const char *szName )
}
}
void CAssetManager::UnrefModel( uint32_t uIndex )
void C_AssetManager::UnrefModel( uint32_t uIndex )
{
}
void CAssetManager::LoadMaterialData( CBaseMaterial *pMaterial, IJSONObject *pObj )
void C_AssetManager::LoadMaterialData( CBaseMaterial *pMaterial, IJSONObject *pObj )
{
for ( int i = 0; i < pMaterial->GetDataMap()->m_iNumFields; i++ )
{
@@ -236,7 +236,7 @@ void CAssetManager::LoadMaterialData( CBaseMaterial *pMaterial, IJSONObject *pOb
}
uint32_t CAssetManager::LoadMaterial( const char *szName )
uint32_t C_AssetManager::LoadMaterial( const char *szName )
{
bool bHasBeenCreated = false;
HFunnyMaterial hMaterial = m_materials.GetOrCreateObject(szName, &bHasBeenCreated);
@@ -288,12 +288,12 @@ uint32_t CAssetManager::LoadMaterial( const char *szName )
return hMaterial;
}
void CAssetManager::UnrefMaterial( uint32_t uIndex )
void C_AssetManager::UnrefMaterial( uint32_t uIndex )
{
}
HFunnyMesh CAssetManager::LoadMesh( const char *szName )
HFunnyMesh C_AssetManager::LoadMesh( const char *szName )
{
bool bHasBeenCreated = false;
HFunnyMesh hAsset = m_meshes.GetOrCreateObject(szName, &bHasBeenCreated);
@@ -322,12 +322,12 @@ HFunnyMesh CAssetManager::LoadMesh( const char *szName )
return hAsset;
}
void CAssetManager::UnrefMesh( uint32_t uIndex )
void C_AssetManager::UnrefMesh( uint32_t uIndex )
{
m_meshes.UnrefObject(uIndex);
}
uint32_t CAssetManager::LoadShader( const char *szName )
uint32_t C_AssetManager::LoadShader( const char *szName )
{
bool bHasBeenCreated = false;
uint32_t hShader = m_shaders.GetOrCreateObject(szName, &bHasBeenCreated);
@@ -347,12 +347,12 @@ uint32_t CAssetManager::LoadShader( const char *szName )
return hShader;
}
void CAssetManager::UnrefShader( uint32_t uIndex )
void C_AssetManager::UnrefShader( uint32_t uIndex )
{
m_shaders.UnrefObject(uIndex);
}
HFunnyTexture CAssetManager::LoadTexture( const char *szName )
HFunnyTexture C_AssetManager::LoadTexture( const char *szName )
{
bool bHasBeenCreated = false;
uint32_t hTexture = m_textures.GetOrCreateObject(szName, &bHasBeenCreated);
@@ -372,18 +372,18 @@ HFunnyTexture CAssetManager::LoadTexture( const char *szName )
return hTexture;
}
FunnyTexture_t *CAssetManager::GetTextureByIndex( HFunnyTexture hTexture )
FunnyTexture_t *C_AssetManager::GetTextureByIndex( HFunnyTexture hTexture )
{
return m_textures.GetObjectPtr(hTexture);
}
void CAssetManager::UnrefTexture( uint32_t hTexture )
void C_AssetManager::UnrefTexture( uint32_t hTexture )
{
}
HFunnyPhysics CAssetManager::LoadPhysics( const char *szName )
HFunnyPhysics C_AssetManager::LoadPhysics( const char *szName )
{
bool bHasBeenCreated = false;
HFunnyPhysics hPhysics = m_physics.GetOrCreateObject(szName, &bHasBeenCreated);
@@ -436,12 +436,12 @@ HFunnyPhysics CAssetManager::LoadPhysics( const char *szName )
}
FunnyPhysics_t *CAssetManager::GetPhysicsByIndex( HFunnyPhysics hPhysics )
FunnyPhysics_t *C_AssetManager::GetPhysicsByIndex( HFunnyPhysics hPhysics )
{
return m_physics.GetObjectPtr(hPhysics);
}
void CAssetManager::UnrefPhysics( HFunnyPhysics hPhysics )
void C_AssetManager::UnrefPhysics( HFunnyPhysics hPhysics )
{
m_physics.UnrefObject(hPhysics);
}
@@ -449,5 +449,5 @@ void CAssetManager::UnrefPhysics( HFunnyPhysics hPhysics )
static CAssetManager s_assetmgr;
static C_AssetManager s_assetmgr;
IAssetManager *g_pAssetManager = &s_assetmgr;
+4 -4
View File
@@ -20,7 +20,7 @@
typedef className ThisClass;
#define LINK_ENTITY_TO_CLASS( mapClassName, DLLClassName) \
static CEntityFactory<DLLClassName> g_EntityFactory_##mapClassName( #mapClassName ); \
static C_EntityFactory<DLLClassName> g_EntityFactory_##mapClassName( #mapClassName ); \
class C_BaseEntity;
@@ -32,12 +32,12 @@ public:
template<class T>
class CEntityFactory : public IEntityFactory
class C_EntityFactory : public IEntityFactory
{
public:
CEntityFactory( const char *szClassName )
C_EntityFactory( const char *szClassName )
{
EntitySystem()->RegisterEntityClass(this, szClassName);
ClientEntitySystem()->RegisterEntityClass(this, szClassName);
};
virtual C_BaseEntity *Create() {
return new T;
+2 -3
View File
@@ -25,7 +25,7 @@ void C_BaseModelEntity::Think( float fDelta )
void C_BaseModelEntity::SetModel( const char *szName )
{
V_memset(m_szModel, 0, 256);
V_strncpy(m_szModel, szName, 255);
V_memcpy(m_szModel, szName, 256);
}
void C_BaseModelEntity::UpdateModel()
@@ -33,8 +33,7 @@ void C_BaseModelEntity::UpdateModel()
if (!V_strncmp(m_szModel, m_szCurrentModel, 256))
return;
V_memset(m_szCurrentModel, 0, 256);
V_strncpy(m_szCurrentModel, m_szModel, 255);
V_memcpy(m_szCurrentModel, m_szModel, 256);
if (m_hModelHandle)
{
+5 -5
View File
@@ -14,7 +14,7 @@
static C_BaseEntity *s_pLocalEntity;
C_EntitySystem *EntitySystem()
C_EntitySystem *ClientEntitySystem()
{
static C_EntitySystem s_entitySystem;
return &s_entitySystem;
@@ -25,7 +25,7 @@ static struct EntityRegistry_t
IEntityFactory *m_pFactory;
const char *m_szClassName;
struct EntityRegistry_t *m_pNext;
} *s_pEntitiesRegistry = NULL;
} *s_pClientEntitiesRegistry = NULL;
C_EntitySystem::C_EntitySystem()
{
@@ -52,9 +52,9 @@ void C_EntitySystem::RegisterEntityClass( IEntityFactory *pEntityFactory, const
pRegistry = new EntityRegistry_t;
pRegistry->m_pFactory = pEntityFactory;
pRegistry->m_pNext = s_pEntitiesRegistry;
pRegistry->m_pNext = s_pClientEntitiesRegistry;
pRegistry->m_szClassName = szClassName;
s_pEntitiesRegistry = pRegistry;
s_pClientEntitiesRegistry = pRegistry;
}
C_BaseEntity *C_EntitySystem::CreateByClassname( const char *szName )
@@ -113,7 +113,7 @@ IEntityFactory *C_EntitySystem::GetFactoryByClassname( const char *szName )
{
EntityRegistry_t *pEntity;
for ( pEntity = s_pEntitiesRegistry; pEntity; pEntity = pEntity->m_pNext )
for ( pEntity = s_pClientEntitiesRegistry; pEntity; pEntity = pEntity->m_pNext )
{
if (!strcmp(szName, pEntity->m_szClassName))
{
+1 -1
View File
@@ -43,7 +43,7 @@ private:
int m_nEntityCount;
};
C_EntitySystem *EntitySystem();
C_EntitySystem *ClientEntitySystem();
C_BaseEntity *UTIL_GetLocalPlayer();
+15 -16
View File
@@ -15,7 +15,7 @@
#include "steam/steam_gameserver.h"
#endif
class CFunnyGameBridge: public IEngineBridge
class CClientGameBridge: public IEngineBridge
{
virtual void Init() override;
virtual void Tick( float fDelta ) override;
@@ -33,18 +33,18 @@ class CFunnyGameBridge: public IEngineBridge
};
IEngineBridge *EngineBridge()
IEngineBridge *ClientEngineBridge()
{
static CFunnyGameBridge s_bridge;
static CClientGameBridge s_bridge;
return &s_bridge;
}
void XRInputCallback( IXRController *pController, EXRInputType_t eType, const char *szType, EXRInputActionType_t action, EXRInputValue_t value );
EXPOSE_INTERFACE_FN(EngineBridge, IEngineBridge, ENGINE_BRIDGE_INTERFACE_VERSION)
EXPOSE_INTERFACE_FN(ClientEngineBridge, IClientEngineBridge, CLIENT_ENGINE_BRIDGE_INTERFACE_VERSION)
void CFunnyGameBridge::Init()
void CClientGameBridge::Init()
{
Console()->AddCommand("exec game/core/default.cfg\n");
Console()->Execute();
@@ -121,12 +121,12 @@ void CFunnyGameBridge::Init()
*/
}
void CFunnyGameBridge::Tick( float fDelta )
void CClientGameBridge::Tick( float fDelta )
{
}
void CFunnyGameBridge::TryToConnectToServer()
void CClientGameBridge::TryToConnectToServer()
{
#ifdef STEAM
if (g_pEngineConstants->m_bIsSteam)
@@ -145,10 +145,10 @@ void CFunnyGameBridge::TryToConnectToServer()
if (g_pServerConnection)
{
m_bIsConnectedToServer = true;
C_BaseEntity **ppEntities = EntitySystem()->GetEntities();
C_BaseEntity **ppEntities = ClientEntitySystem()->GetEntities();
for ( int i = 0; i < MAX_EDICTS; i++ )
{
EntitySystem()->DestroyEntityByIndex(i);
ClientEntitySystem()->DestroyEntityByIndex(i);
}
}
return;
@@ -156,9 +156,8 @@ void CFunnyGameBridge::TryToConnectToServer()
#endif
}
void CFunnyGameBridge::Frame( float fDelta )
void CClientGameBridge::Frame( float fDelta )
{
if (g_pMainWindow->GetRenderWidth() != m_pMainViewport->GetWidth())
if (g_pMainWindow->GetRenderHeight() != m_pMainViewport->GetHeight())
m_pMainViewport->UpdateResolution(g_pMainWindow->GetRenderWidth(), g_pMainWindow->GetRenderHeight());
@@ -198,7 +197,7 @@ void CFunnyGameBridge::Frame( float fDelta )
case MESSAGE_ENTITY_CLASS_SYNC:
case MESSAGE_ENTITY_DATA_SYNC:
case k_EMessage_PlayerSetLocalEntity:
EntitySystem()->NetRecvPacket(&packet);
ClientEntitySystem()->NetRecvPacket(&packet);
pCurrentServer->RecievePacket();
break;
default:
@@ -209,7 +208,7 @@ void CFunnyGameBridge::Frame( float fDelta )
}
}
EntitySystem()->Think();
ClientEntitySystem()->Think();
float fTickRate = 1.0/60.0;
m_fNetUpdateTimer += fDelta;
@@ -220,19 +219,19 @@ void CFunnyGameBridge::Frame( float fDelta )
m_fNetUpdateTimer-=fTickRate;
m_fNetUpdateTimer = fmod(m_fNetUpdateTimer, fTickRate);
if (pCurrentServer)
EntitySystem()->NetSendThink(pCurrentServer);
ClientEntitySystem()->NetSendThink(pCurrentServer);
}
g_pWorldRenderer->Frame(fDelta);
g_pMainWindow->SetOutputImage(m_pMainViewport->GetRenderImage());
}
void CFunnyGameBridge::Shutdown()
void CClientGameBridge::Shutdown()
{
}
#define CONNECT_INTERFACE(szName, pGlobal) if (!V_strcmp(psz, szName)) { pGlobal = (typeof(pGlobal))pInterface; return; }
void CFunnyGameBridge::ConnectInterface( const char *psz, void *pInterface )
void CClientGameBridge::ConnectInterface( const char *psz, void *pInterface )
{
CONNECT_INTERFACE(FILESYSTEM_INTERFACE_VERSION, filesystem);
CONNECT_INTERFACE(RENDER_CONTEXT_INTERFACE_VERSION, g_pRenderContext);
+2 -4
View File
@@ -26,8 +26,8 @@ void C_MOBAPlayer::Think( float fDelta )
if (pPlayerEntity == this)
{
}
m_pLeftHand = (C_MOBAPlayerHandController*)EntitySystem()->GetEntityByIndex(m_leftHandId);
m_pRightHand = (C_MOBAPlayerHandController*)EntitySystem()->GetEntityByIndex(m_rightHandId);
m_pLeftHand = (C_MOBAPlayerHandController*)ClientEntitySystem()->GetEntityByIndex(m_leftHandId);
m_pRightHand = (C_MOBAPlayerHandController*)ClientEntitySystem()->GetEntityByIndex(m_rightHandId);
BaseClass::Think(fDelta);
};
@@ -157,10 +157,8 @@ void Game_OnGameAxisDiff( EInputDeviceType eDevice, EInputAxis eAxis, float fVal
}
}
void C_MOBAPlayerHandController::Precache()
{
m_hNormal = g_pAssetManager->LoadModel("game/core/models/hand.fmdl");
m_pNormalModel = g_pAssetManager->GetModelByIndex(m_hNormal);
m_hSqueezed = g_pAssetManager->LoadModel("game/core/models/sphere.fmdl");
+1 -1
View File
@@ -367,7 +367,7 @@ void CFunnyWorldRenderer::Frame( float fDelta )
v->m_pDepth,
LOAD_MODE_CLEAR,
STORE_MODE_STORE,
{.depth = 0},
{.depth = 1},
};
BeginInfo begin = {};
begin.uWidth = uWidth;
+2 -2
View File
@@ -295,5 +295,5 @@ void CAssetManager::UnrefPhysics( HFunnyPhysics hPhysics )
static CAssetManager s_assetmgr;
IAssetManager *g_pAssetManager = &s_assetmgr;
static CAssetManager s_server_assetmgr;
IAssetManager *g_pServerAssetManager = &s_server_assetmgr;
+1 -1
View File
@@ -58,6 +58,6 @@ public:
virtual void UnrefPhysics( HFunnyPhysics hPhysics ) = 0;
};
extern IAssetManager *g_pAssetManager;
extern IAssetManager *g_pServerAssetManager;
#endif
+1 -2
View File
@@ -21,8 +21,7 @@ void CBaseModelEntity::Think( float fDelta )
{
if (V_strncmp(m_szModel, m_szCurrentModel, 256))
{
V_memset(m_szCurrentModel, 0, 256);
V_strncpy(m_szCurrentModel, m_szModel, 255);
V_memcpy(m_szCurrentModel, m_szModel, 256);
OnModelChanged(m_szCurrentModel);
}
}
-1
View File
@@ -17,7 +17,6 @@ public:
virtual void OnModelChanged( const char *szName );
void Think( float fDelta );
char m_szModel[256] = {};
private:
char m_szCurrentModel[256] = {};
};
+26 -7
View File
@@ -63,14 +63,14 @@ CBaseEntity *CEntitySystem::CreateByClassname( const char *szName, int *pOutputI
int i;
int iSelectedSlot;
pFactory = GetFactoryByClassname(szName);
if ( !pFactory )
return NULL;
// We do not want to have more than MAX_EDICT entities
if ( m_nEntityCount >= MAX_EDICTS-1 )
return NULL;
pFactory = GetFactoryByClassname(szName);
if ( !pFactory )
return NULL;
// Search for space
// Could be more efficient but nobody cares
for ( i = 0; i < MAX_EDICTS; i++ )
@@ -112,7 +112,6 @@ IEntityFactory *CEntitySystem::GetFactoryByClassname( const char *szName )
}
return NULL;
}
void CEntitySystem::Think( float fDelta )
{
CBaseEntity *pEntity;
@@ -120,7 +119,6 @@ void CEntitySystem::Think( float fDelta )
for ( i = 0; i < MAX_EDICTS; i++ )
{
pEntity = m_pEntities[i];
if ( pEntity == NULL )
continue;
@@ -150,6 +148,23 @@ searchIndex:
return NULL;
}
static netfield_t *UTIL_GetNetMapField( CBaseEntity *pEntity, netmap_t *pMap, uint32_t uIndex )
{
netmap_t *pCurrentMap = pMap;
uint32_t uCurrentIndex = uIndex;
searchIndex:
if ( pCurrentMap )
{
if (uCurrentIndex >= pCurrentMap->m_uFieldCount)
{
uCurrentIndex -= pCurrentMap->m_uFieldCount;
pCurrentMap = pCurrentMap->m_pBase;
goto searchIndex;
}
return &pCurrentMap->m_pFields[uCurrentIndex];
}
return NULL;
}
void CEntitySystem::NetRecvPacket( NetPacket_t *pPacket )
{
@@ -182,9 +197,13 @@ void CEntitySystem::NetRecvPacket( NetPacket_t *pPacket )
// this shall be reworked
for ( uint32_t u = 0; u < pPlayerPacket->m_entityData.m_uCount; u++ )
{
netfield_t *pnf = UTIL_GetNetMapField(
pEntity,
pEntity->GetRecvMap(),
pcSyncValue->m_uVariableIndex);
uint32_t uVariableSize = pcSyncValue->m_uVariableSize;
void *pValueData = (float*)UTIL_GetNetMapData(
void *pValueData = UTIL_GetNetMapData(
pEntity,
pEntity->GetRecvMap(),
pcSyncValue->m_uVariableIndex);
+2 -2
View File
@@ -34,8 +34,8 @@ public:
virtual void NetSendThink( INetworkBase *pBase );
virtual void SetAllowedEntityForPlayer( uint64_t ullPlayer, CBaseEntity *pEntity );
private:
CBaseEntity *m_pEntities[MAX_EDICTS];
int m_nEntityCount;
CBaseEntity *m_pEntities[MAX_EDICTS] = {};
int m_nEntityCount = 0;
};
CEntitySystem *EntitySystem();
+9 -9
View File
@@ -11,7 +11,7 @@
#include "steam/steam_gameserver.h"
#endif
class CFunnyGameBridge: public IEngineBridge
class CServerGameBridge: public IEngineBridge
{
virtual void Init() override;
virtual void Tick( float fDelta ) override;
@@ -24,13 +24,13 @@ class CFunnyGameBridge: public IEngineBridge
};
IEngineBridge *EngineBridge()
IEngineBridge *ServerEngineBridge()
{
static CFunnyGameBridge s_bridge;
static CServerGameBridge s_bridge;
return &s_bridge;
}
EXPOSE_INTERFACE_FN(EngineBridge, IEngineBridge, ENGINE_BRIDGE_INTERFACE_VERSION)
EXPOSE_INTERFACE_FN(ServerEngineBridge, IServerEngineBridge, SERVER_ENGINE_BRIDGE_INTERFACE_VERSION)
uint32_t NET_ServerCallback( NetCallback_t *pCallback )
{
@@ -97,7 +97,7 @@ uint32_t NET_ServerCallback( NetCallback_t *pCallback )
return 0;
}
void CFunnyGameBridge::Init()
void CServerGameBridge::Init()
{
if (g_pEngineConstants->m_bIsDedicated == false)
g_pClientBridge = g_pEngineConstants->LaunchLocalBridge(0);
@@ -145,7 +145,7 @@ void CFunnyGameBridge::Init()
}
void CFunnyGameBridge::Tick( float fDelta )
void CServerGameBridge::Tick( float fDelta )
{
}
@@ -196,7 +196,7 @@ void NET_ProcessPacket( INetworkBase *pBase )
pBase->RecievePacket();
}
void CFunnyGameBridge::Frame( float fDelta )
void CServerGameBridge::Frame( float fDelta )
{
g_pEngineVars->m_fTime += fDelta;
g_pEngineVars->m_fDeltaTime = fDelta;
@@ -242,13 +242,13 @@ void CFunnyGameBridge::Frame( float fDelta )
}
void CFunnyGameBridge::Shutdown()
void CServerGameBridge::Shutdown()
{
}
#define CONNECT_INTERFACE(szName, pGlobal) if (!V_strcmp(psz, szName)) { pGlobal = (typeof(pGlobal))pInterface; return; }
void CFunnyGameBridge::ConnectInterface( const char *psz, void *pInterface )
void CServerGameBridge::ConnectInterface( const char *psz, void *pInterface )
{
CONNECT_INTERFACE(FILESYSTEM_INTERFACE_VERSION, filesystem);
CONNECT_INTERFACE("EngineConstants", g_pEngineConstants)
+2 -1
View File
@@ -5,7 +5,6 @@
CMOBAPlayer::CMOBAPlayer()
{
m_hCuboid = g_pPhysics->CreateCube({1,1,1});
}
CMOBAPlayer::~CMOBAPlayer()
@@ -20,6 +19,8 @@ void CMOBAPlayer::Spawn()
SetAbsOrigin({0,-11.5, 0});
SetThink(Think);
m_hCuboid = g_pPhysics->CreateCube({1,1,1});
m_pLeftHand = EntitySystem()->CreateByClassname("player_hand_controller", &m_leftHandId);
m_pRightHand = EntitySystem()->CreateByClassname("player_hand_controller", &m_rightHandId);
m_pLeftHand->Spawn();
+4 -4
View File
@@ -61,11 +61,11 @@ void CPhysicsProp::OnModelChanged( const char *szName )
{
if (m_hModel)
{
g_pAssetManager->UnrefModel(m_hModel);
g_pServerAssetManager->UnrefModel(m_hModel);
}
m_hModel = g_pAssetManager->LoadModel(szName);
m_pModel = g_pAssetManager->GetModelByIndex(m_hModel);
m_pPhysics = g_pAssetManager->GetPhysicsByIndex(m_pModel->m_hPhysics);
m_hModel = g_pServerAssetManager->LoadModel(szName);
m_pModel = g_pServerAssetManager->GetModelByIndex(m_hModel);
m_pPhysics = g_pServerAssetManager->GetPhysicsByIndex(m_pModel->m_hPhysics);
m_hCollider = g_pPhysics->CreateCollider(m_pPhysics->m_hShape);
m_pBody = g_pPhysicsWorld->CreateRigidBody(m_hCollider, m_eCurrentPhysicsType);
m_pBody->SetPosition(GetAbsOrigin());
+65 -22
View File
@@ -11,8 +11,12 @@ ADD_DEPENDENCY_BUILD_FILE(ms, "../materialsystem/build.cpp");
ADD_DEPENDENCY_BUILD_FILE(fs, "../external/funnystdlib/stdfilesystems/build.cpp");
ADD_DEPENDENCY_BUILD_FILE(tier0, "../external/funnystdlib/tier0/build.cpp");
ADD_DEPENDENCY_BUILD_FILE(tier1, "../external/funnystdlib/tier1/build.cpp");
ADD_DEPENDENCY_BUILD_FILE(tier2, "../external/funnystdlib/tier2/build.cpp");
ADD_DEPENDENCY_BUILD_FILE(server, "../game/server/build.cpp");
ADD_DEPENDENCY_BUILD_FILE(client, "../game/client/build.cpp");
ADD_DEPENDENCY_BUILD_FILE(rapier, "../rapier/build.cpp");
#define EXTERNAL "../external/"
DECLARE_BUILD_STAGE(launcher)
{
@@ -22,13 +26,30 @@ DECLARE_BUILD_STAGE(launcher)
compileProject.files = {"launcher.cpp"};
compileProject.includeDirectories = {"../external/SDL/include"};
compileProject.m_target = Target_t::DefaultTarget();
if (compileProject.m_target.kernel == TARGET_KERNEL_ANDROID)
{
compileProject.files.AppendTail(EXTERNAL "android/android_native_app_glue.c");
compileProject.includeDirectories.AppendTail(EXTERNAL "android");
compileProject.bFPIC = true;
}
ldProject = ccompiler->Compile(&compileProject);
ldProject.linkType = ELINK_EXECUTABLE;
if (compileProject.m_target.kernel == TARGET_KERNEL_ANDROID)
ldProject.linkType = ELINK_DYNAMIC_LIBRARY;
else
ldProject.linkType = ELINK_EXECUTABLE;
if (compileProject.m_target.kernel == TARGET_KERNEL_IOS)
{
ldProject.frameworkDirectories = {"../external/ios"};
ldProject.frameworks = {"SDL3"};
}
if (compileProject.m_target.kernel == TARGET_KERNEL_ANDROID)
{
ldProject.libraries.AppendTail("android");
ldProject.libraries.AppendTail("log");
if (compileProject.m_target.cpu == TARGET_CPU_AARCH64)
ldProject.libraryDirectories.AppendTail(EXTERNAL "android/aarch64");
}
if ( GET_PROJECT_VALUE(config, "static") == "true" )
{
ldProject.objects.AppendTail({GET_PROJECT_OBJECT(engine, "engine")});
@@ -36,10 +57,15 @@ DECLARE_BUILD_STAGE(launcher)
ldProject.objects.AppendTail({GET_PROJECT_OBJECT(RenderSystemVulkan, "RenderSystemVulkan")});
ldProject.objects.AppendTail({GET_PROJECT_OBJECT(tier0, "libtier0")});
ldProject.objects.AppendTail({GET_PROJECT_OBJECT(tier1, "tier1")});
ldProject.objects.AppendTail({GET_PROJECT_OBJECT(filesystem_std, "libfs")});
ldProject.objects.AppendTail({GET_PROJECT_OBJECT(tier2, "tier2")});
if (ldProject.m_target.kernel != TARGET_KERNEL_ANDROID)
ldProject.objects.AppendTail({GET_PROJECT_OBJECT(filesystem_std, "libfs")});
ldProject.objects.AppendTail({GET_PROJECT_OBJECT(shadercompiler, "fs")});
ldProject.objects.AppendTail({GET_PROJECT_OBJECT(Server, "server")});
ldProject.objects.AppendTail({GET_PROJECT_OBJECT(Client, "client")});
ldProject.objects.AppendTail({GET_PROJECT_OBJECT(rapier, "physics")});
ldProject.objects.AppendTail({GET_PROJECT_OBJECT(rapier, "rapier_static")});
ldProject.libraries.AppendTail("openxr_loader");
}
CUtlString outputProject = linker->Link(&ldProject);
@@ -52,16 +78,16 @@ DECLARE_BUILD_STAGE(launcher)
CUtlString szOutputDir = manifest.BuildManifest();
filesystem2->CopyDirectory(CUtlString("%s/core/",szOutputDir.GetString()), "../funnyassets/maps");
filesystem2->CopyDirectory(CUtlString("%s/core/",szOutputDir.GetString()), "../funnyassets/models");
filesystem2->CopyDirectory(CUtlString("%s/core/",szOutputDir.GetString()), "../funnyassets/meshes");
filesystem2->CopyDirectory(CUtlString("%s/core/",szOutputDir.GetString()), "../funnyassets/materials");
filesystem2->CopyDirectory(CUtlString("%s/core/",szOutputDir.GetString()), "../funnyassets/textures");
filesystem2->CopyDirectory(CUtlString("%s/core/",szOutputDir.GetString()), "../funnyassets/physics");
filesystem2->CopyFile(CUtlString("%s/core/",szOutputDir.GetString()), "../funnyassets/default.cfg");
filesystem2->CopyDirectory(CUtlString("%s/core/",szOutputDir.GetString()), "../funnyassets/game/maps");
filesystem2->CopyDirectory(CUtlString("%s/core/",szOutputDir.GetString()), "../funnyassets/game/models");
filesystem2->CopyDirectory(CUtlString("%s/core/",szOutputDir.GetString()), "../funnyassets/game/meshes");
filesystem2->CopyDirectory(CUtlString("%s/core/",szOutputDir.GetString()), "../funnyassets/game/materials");
filesystem2->CopyDirectory(CUtlString("%s/core/",szOutputDir.GetString()), "../funnyassets/game/textures");
filesystem2->CopyDirectory(CUtlString("%s/core/",szOutputDir.GetString()), "../funnyassets/game/physics");
filesystem2->CopyFile(CUtlString("%s/core/",szOutputDir.GetString()), "../funnyassets/game/default.cfg");
filesystem2->CopyDirectory(szOutputDir, "../external/ios/SDL3.framework");
filesystem2->CopyDirectory(CUtlString("%s/core/",szOutputDir.GetString()), "../build/funnygame/assets/shaders");
filesystem2->CopyDirectory(CUtlString("%s/core/",szOutputDir.GetString()), "../build/funnygame/assets/game/shaders");
CUtlString szIpa = AppleTool()->BuildPackage( manifest, szOutputDir );
}
if (compileProject.m_target.kernel == TARGET_KERNEL_ANDROID)
@@ -74,20 +100,37 @@ DECLARE_BUILD_STAGE(launcher)
CUtlString szOutputDir = manifest.BuildManifest();
CUtlString szLibDir = CUtlString("%s/lib/%s",szOutputDir.GetString(), Target_t::StringFromCPU(compileProject.m_target.cpu));
filesystem2->MakeDirectory(szLibDir);
filesystem2->CopyFile(CUtlString("%s/libnative-app.so",szLibDir.GetString()), outputProject);
CUtlVector<CUtlString> libdirs = {};
CUtlString nativelibs;
if (compileProject.m_target.cpu == TARGET_CPU_AARCH64)
{
libdirs.AppendTail(CUtlString("%s/lib/aarch64",szOutputDir.GetString()));
libdirs.AppendTail(CUtlString("%s/lib/arm64-v8a",szOutputDir.GetString()));
nativelibs.AppendTail(EXTERNAL "android/aarch64");
}
for (auto lib: libdirs)
{
filesystem2->MakeDirectory(lib);
filesystem2->CopyFile(CUtlString("%s/libnative-app.so",lib.GetString()), outputProject);
filesystem2->CopyFile(lib, CUtlString("%s/libc++_shared.so",nativelibs.GetString()));
filesystem2->CopyFile(lib, CUtlString("%s/libopenxr_loader.so",nativelibs.GetString()));
filesystem2->CopyFile(lib, CUtlString("%s/libVkLayer_khronos_validation.so",nativelibs.GetString()));
}
filesystem2->MakeDirectory(CUtlString("%s/assets/core/",szOutputDir.GetString()));
filesystem2->CopyDirectory(CUtlString("%s/assets/core/",szOutputDir.GetString()), "../funnyassets/maps");
filesystem2->CopyDirectory(CUtlString("%s/assets/core/",szOutputDir.GetString()), "../funnyassets/models");
filesystem2->CopyDirectory(CUtlString("%s/assets/core/",szOutputDir.GetString()), "../funnyassets/meshes");
filesystem2->CopyDirectory(CUtlString("%s/assets/core/",szOutputDir.GetString()), "../funnyassets/materials");
filesystem2->CopyDirectory(CUtlString("%s/assets/core/",szOutputDir.GetString()), "../funnyassets/textures");
filesystem2->CopyDirectory(CUtlString("%s/assets/core/",szOutputDir.GetString()), "../funnyassets/physics");
filesystem2->CopyFile(CUtlString("%s/assets/core/",szOutputDir.GetString()), "../funnyassets/default.cfg");
manifest.AddObject("lib");
manifest.AddObject("assets");
filesystem2->CopyDirectory(CUtlString("%s/assets/core/",szOutputDir.GetString()), "../build/funnygame/assets/shaders");
filesystem2->MakeDirectory(CUtlString("%s/assets/game/core/",szOutputDir.GetString()));
filesystem2->CopyDirectory(CUtlString("%s/assets/game/core/",szOutputDir.GetString()), "../funnyassets/maps");
filesystem2->CopyDirectory(CUtlString("%s/assets/game/core/",szOutputDir.GetString()), "../funnyassets/models");
filesystem2->CopyDirectory(CUtlString("%s/assets/game/core/",szOutputDir.GetString()), "../funnyassets/meshes");
filesystem2->CopyDirectory(CUtlString("%s/assets/game/core/",szOutputDir.GetString()), "../funnyassets/materials");
filesystem2->CopyDirectory(CUtlString("%s/assets/game/core/",szOutputDir.GetString()), "../funnyassets/textures");
filesystem2->CopyDirectory(CUtlString("%s/assets/game/core/",szOutputDir.GetString()), "../funnyassets/physics");
filesystem2->CopyFile(CUtlString("%s/assets/game/core/",szOutputDir.GetString()), "../funnyassets/default.cfg");
filesystem2->CopyDirectory(CUtlString("%s/assets/game/core/",szOutputDir.GetString()), "../build/funnygame/assets/shaders");
CUtlString szApkPackage = APKTool()->BuildPackage( manifest, szOutputDir );
APKTool()->SignPackage(szApkPackage, NULL, "kotofyt", "password1", "password1");
}
+11 -3
View File
@@ -37,9 +37,12 @@ void *pEngineLib = NULL;
void *pTier0Lib = NULL;
typedef void (*EngineMainFn)(int argc, char** argv);
EngineMainFn pEngineMain;
extern void FunnyMain(int argc, char** argv);
extern "C" void FunnyMain(int argc, char** argv);
int main( int argc, char **argv ) {
#ifdef __ANDROID__
FunnyMain(argc, argv);
#endif
#ifdef __linux__
readlink("/proc/self/exe",szLauncherPath, MAX_PATH);
dirname(szLauncherPath);
@@ -100,14 +103,19 @@ int main( int argc, char **argv ) {
SetCurrentDirectoryA(szLauncherPath);
pEngineMain(argc, argv);
#endif
FunnyMain(argc, argv);
return 0;
};
#ifdef __ANDROID__
#include <android/log.h>
#include <android_native_app_glue.h>
struct android_app *g_android_app;
void android_main(struct android_app* app)
{
g_android_app = app;
const char *arg = "funnygame";
FunnyMain(1, (char**)&arg);
}
#endif
+10 -1
View File
@@ -33,7 +33,6 @@ CUtlVector<CUtlString> RenderContextVulkan_CompiledFiles = {
"vulkan/commands/base.cpp",
"vulkan/libraries/raster.cpp",
EXTERNAL"volk/volk.c",
"gamewindow_sdl.cpp",
"stb.c",
};
@@ -89,6 +88,16 @@ DECLARE_BUILD_STAGE(RenderSystemVulkan)
compileProject.m_szName = "RenderSystemVulkan";
compileProject.files = RenderContextVulkan_CompiledFiles;
if (Target_t::DefaultTarget().kernel == TARGET_KERNEL_ANDROID)
{
compileProject.files.AppendTail("gamewindow_android.cpp");
compileProject.macros = {
(C_Macro_t){"VK_USE_PLATFORM_ANDROID_KHR"}
};
}
else
compileProject.files.AppendTail("gamewindow_sdl.cpp");
compileProject.includeDirectories = {
"../public",
FUNNYSTDLIB"public",
+224
View File
@@ -0,0 +1,224 @@
#include "android/android_native_app_glue.h"
#include "materialsystem/igamewindow.h"
#include "tier0/lib.h"
#include "tier0/platform.h"
#include "tier1/interface.h"
#include "tier1/utlvector.h"
#include "volk.h"
extern struct android_app *g_android_app;
class CAndroidGameWindow: public IGameWindow
{
public:
virtual void Init() override;
virtual void Shutdown() override;
virtual void Frame( float fDelta ) override;
virtual uint32_t GetRenderWidth() override;
virtual uint32_t GetRenderHeight() override;
virtual bool BRenderSizeUpdated() override;
virtual void SetOutputImage( IImage *pImage ) override;
virtual IImage *GetOutputImage() override;
virtual void SetKeyCallback( KeyCallbackFn fn ) override;
virtual void SetAxisCallback( AxisCallbackFn fn ) override;
virtual void *CreateVulkanSurface( void *pInstance ) override;
virtual void DestroyVulkanSurface( void *pInstance ) override;
virtual bool IsValid() override;
KeyCallbackFn m_fnKeyCallback = NULL;
AxisCallbackFn m_fnAxisCallback = NULL;
bool m_bWindowSizeUpdated;
uint32_t m_uRenderWidth;
uint32_t m_uRenderHeight;
bool m_bIsValid = false;
private:
VkSurfaceKHR m_hSurface = NULL;
IImage *m_pOutputImage = NULL;
};
void CAndroidGameWindow::Init()
{
m_uRenderWidth = 1280;
m_uRenderHeight = 720;
}
void CAndroidGameWindow::Shutdown()
{
}
void CAndroidGameWindow::Frame( float fDelta )
{
}
uint32_t CAndroidGameWindow::GetRenderWidth()
{
return m_uRenderWidth;
}
uint32_t CAndroidGameWindow::GetRenderHeight()
{
return m_uRenderHeight;
}
bool CAndroidGameWindow::BRenderSizeUpdated()
{
return m_bWindowSizeUpdated;
}
void CAndroidGameWindow::SetOutputImage( IImage *pImage )
{
m_pOutputImage = pImage;
}
IImage *CAndroidGameWindow::GetOutputImage()
{
return m_pOutputImage;
}
void CAndroidGameWindow::SetKeyCallback( KeyCallbackFn fn )
{
m_fnKeyCallback = fn;
}
void CAndroidGameWindow::SetAxisCallback( AxisCallbackFn fn )
{
m_fnAxisCallback = fn;
}
void *CAndroidGameWindow::CreateVulkanSurface( void *pInstance )
{
VkAndroidSurfaceCreateInfoKHR ci = {};
ci.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR;
ci.window = g_android_app->window;
vkCreateAndroidSurfaceKHR((VkInstance)pInstance, &ci, NULL, &m_hSurface);
return m_hSurface;
}
void CAndroidGameWindow::DestroyVulkanSurface( void *pInstance )
{
vkDestroySurfaceKHR((VkInstance)pInstance, m_hSurface, NULL);
}
bool CAndroidGameWindow::IsValid()
{
return m_bIsValid;
}
class CAndroidGameWindowManager: public IGameWindowManager
{
public:
virtual void Init() override;
virtual void Frame( float fDelta ) override;
virtual void Shutdown() override;
virtual IGameWindow *CreateWindow() override;
virtual void DestroyWindow( IGameWindow* pWindow ) override;
virtual int GetVulkanInstanceExtensionCount() override;
virtual const char **GetVulkanInstanceExtensions() override;
CAndroidGameWindow m_window;
private:
};
IGameWindowManager *GameWindowManager()
{
static CAndroidGameWindowManager mgr;
return &mgr;
}
EXPOSE_INTERFACE_FN(GameWindowManager, IGameWindowManager, GAME_WINDOW_MANAGER_INTERFACE_VERSION)
#include "android/log.h"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, "funnygame", __VA_ARGS__)
static void HandleAndroidEvent(android_app* app, int32_t cmd) {
CAndroidGameWindowManager *pMgr = (CAndroidGameWindowManager*)GameWindowManager();
switch (cmd) {
case APP_CMD_INIT_WINDOW:
pMgr->m_window.m_bIsValid = true;
break;
default:
break;
}
}
void CAndroidGameWindowManager::Init()
{
g_android_app->onAppCmd = HandleAndroidEvent;
while (true)
{
int events;
android_poll_source* source;
while (ALooper_pollOnce(0, nullptr, &events, (void**)&source) >= 0) {
if (source) source->process(g_android_app, source);
}
if (m_window.IsValid())
break;
}
}
/*
static EInputButton GetKeyButton( Android_Keycode eCode )
{
}
*/
void CAndroidGameWindowManager::Frame( float fDelta )
{
m_window.m_bWindowSizeUpdated = false;
int events;
android_poll_source* source;
while (ALooper_pollOnce(0, nullptr, &events, (void**)&source) >= 0) {
if (source) source->process(g_android_app, source);
}
LOGI("%u %u", m_window.m_uRenderWidth, m_window.m_uRenderHeight);
uint32_t uNewWidth = ANativeWindow_getWidth(g_android_app->window);
uint32_t uNewHeight = ANativeWindow_getHeight(g_android_app->window);
if (m_window.m_uRenderWidth != uNewWidth || m_window.m_uRenderHeight != uNewHeight)
{
m_window.m_bWindowSizeUpdated = true;
}
m_window.m_uRenderWidth = uNewWidth;
m_window.m_uRenderHeight = uNewHeight;
}
void CAndroidGameWindowManager::Shutdown()
{
}
IGameWindow *CAndroidGameWindowManager::CreateWindow()
{
return &m_window;
}
void CAndroidGameWindowManager::DestroyWindow( IGameWindow* pWindow )
{
pWindow->Shutdown();
}
int CAndroidGameWindowManager::GetVulkanInstanceExtensionCount()
{
return 2;
}
static const char *extensions[] = {
VK_KHR_ANDROID_SURFACE_EXTENSION_NAME,
VK_KHR_SURFACE_EXTENSION_NAME,
};
const char **CAndroidGameWindowManager::GetVulkanInstanceExtensions()
{
return extensions;
}
+7
View File
@@ -23,6 +23,9 @@ DECLARE_VULKAN_COMMAND(Begin)
{
if (vkCmdBeginRendering || vkCmdBeginRenderingKHR)
{
V_printf("USING DYNAMIC RENDERING\n");
V_printf("%p\n", vkCmdBeginRendering);
V_printf("%p\n", vkCmdBeginRenderingKHR);
VkRenderingInfo stRenderingInfo = {};
CUtlVector<VkRenderingAttachmentInfo> attachments = {};
VkRenderingAttachmentInfo depthAttachment = {};
@@ -75,6 +78,7 @@ DECLARE_VULKAN_COMMAND(Begin)
}
else
{
V_printf("USING RENDERPASS");
CUtlVector<VkAttachmentDescription> attachments = {};
CUtlVector<VkAttachmentReference> input_refs = {};
CUtlVector<VkImageView> image_views = {};
@@ -184,7 +188,10 @@ DECLARE_VULKAN_COMMAND(End)
else if (vkCmdEndRenderingKHR)
vkCmdEndRenderingKHR(hCommandBuffer);
else
{
vkCmdEndRenderPass(hCommandBuffer);
}
}
DECLARE_VULKAN_COMMAND(SetShader)
+8 -1
View File
@@ -8,6 +8,7 @@ void CVkComputeShader::Build()
VulkanInputMetaData_t *pMetaData = (VulkanInputMetaData_t*)m_shader.GetLumpPtr(s->m_nMetadataLump);
VkPipelineLayoutCreateInfo stPipelineLayout = {};
CUtlVector<CUtlVector<VkDescriptorSetLayoutBinding>> bindings = {};
VkShaderModule sm;
for ( int u = 0; u < pMetaData->nDescriptorsCount; u++ )
{
@@ -45,8 +46,14 @@ void CVkComputeShader::Build()
mod.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
mod.pCode = (uint32_t*)m_shader.GetLumpPtr(s->m_nDataLump);
mod.codeSize = m_shader.GetLumpSize(s->m_nDataLump);
if (g_vkAvailableExtensions.bIsSupported_VK_KHR_MAINTENANCE_5)
stage.pNext = &mod;
else
{
vkCreateShaderModule(m_hDevice, &mod, NULL, &sm);
stage.module = sm;
}
stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
stage.pNext = &mod;
stage.pName = "main";
stage.stage = VK_SHADER_STAGE_COMPUTE_BIT;
+1 -1
View File
@@ -6,6 +6,7 @@ REQUIRED_EXTENSION(VK_EXT_DESCRIPTOR_INDEXING)
REQUIRED_EXTENSION(VK_KHR_TIMELINE_SEMAPHORE )
REQUIRED_EXTENSION(VK_KHR_SEPARATE_DEPTH_STENCIL_LAYOUTS)
OPTIONAL_EXTENSION(VK_KHR_RAY_TRACING_PIPELINE)
OPTIONAL_EXTENSION(VK_KHR_CREATE_RENDERPASS_2)
OPTIONAL_EXTENSION(VK_KHR_ACCELERATION_STRUCTURE)
OPTIONAL_EXTENSION(VK_KHR_DEFERRED_HOST_OPERATIONS)
OPTIONAL_EXTENSION(VK_KHR_BUFFER_DEVICE_ADDRESS)
@@ -14,4 +15,3 @@ OPTIONAL_EXTENSION(VK_KHR_MAINTENANCE_5)
//OPTIONAL_EXTENSION(VK_KHR_DYNAMIC_RENDERING)
//OPTIONAL_EXTENSION(VK_KHR_SYNCHRONIZATION2)
//OPTIONAL_EXTENSION(VK_KHR_COPY_COMMANDS2)
//OPTIONAL_EXTENSION(VK_KHR_DYNAMIC_RENDERING)
@@ -42,6 +42,7 @@ void CVkRenderCommandList::Begin( BeginInfo *pBegin )
output.m_eLoadMode = pBegin->pDepth->eLoadMode;
output.m_eStoreMode = pBegin->pDepth->eStoreMode;
pBeginCommand->stDepthImage = output;
pBeginCommand->bDepthEnabled = true;
}
m_pCurrentBegin = pBeginCommand;
m_pCommandBuffer->AddCommand(pBeginCommand);
+9 -9
View File
@@ -228,7 +228,7 @@ void CVkImage::SetDebugName( const char *szName )
nameInfo.objectHandle = (uint64_t)m_image;
nameInfo.pObjectName = szName;
vkSetDebugUtilsObjectNameEXT(s_vkDevice, &nameInfo);
//vkSetDebugUtilsObjectNameEXT(s_vkDevice, &nameInfo);
}
@@ -807,7 +807,7 @@ void CVkRenderContext::Init()
stInstanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
stInstanceCreateInfo.pApplicationInfo = &stApplicationInfo;
enabledInstanceExtensions.AppendTail(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
enabledInstanceExtensions.AppendTail(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
//enabledInstanceExtensions.AppendTail(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
stInstanceCreateInfo.enabledExtensionCount = enabledInstanceExtensions.GetSize();
stInstanceCreateInfo.ppEnabledExtensionNames = enabledInstanceExtensions.GetData();
@@ -898,12 +898,14 @@ void CVkRenderContext::Init()
vkGetDeviceQueue(s_vkDevice, g_iDrawFamily, 0, &s_vkDrawQueue);
vkGetDeviceQueue(s_vkDevice, g_iPresentFamily, 0, &s_vkPresentQueue);
volkLoadDevice(s_vkDevice);
vkCmdBeginRendering = NULL;
vkCmdEndRendering = NULL;
VmaAllocatorCreateInfo stAllocatorInfo = {};
stAllocatorInfo.flags = VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT
| VMA_ALLOCATOR_CREATE_KHR_MAINTENANCE5_BIT
;
stAllocatorInfo.vulkanApiVersion = VK_API_VERSION_1_4;
stAllocatorInfo.flags = VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT;
if (g_vkAvailableExtensions.bIsSupported_VK_KHR_MAINTENANCE_5)
stAllocatorInfo.flags |= VMA_ALLOCATOR_CREATE_KHR_MAINTENANCE5_BIT;
stAllocatorInfo.vulkanApiVersion = VK_API_VERSION_1_1;
stAllocatorInfo.physicalDevice = s_vkPhysicalDevice;
stAllocatorInfo.device = s_vkDevice;
stAllocatorInfo.instance = s_vkInstance;
@@ -946,7 +948,6 @@ void CVkRenderContext::Frame( float fDeltaTime )
{
uint32_t i;
CUtlVector<VkSwapchainKHR> swapchains = {};
CUtlVector<uint32_t> uImageIndexes = {};
CUtlVector<uint32_t> uSwapchainImageIndexes = {};
CUtlVector<VulkanWindow_t> recreatedWindows = {};
@@ -975,7 +976,6 @@ void CVkRenderContext::Frame( float fDeltaTime )
for ( auto &s: m_renderWindows)
{
swapchains.AppendTail(s.m_swapchain);
uImageIndexes.AppendTail(s.m_uCurrentFrame);
}
uSwapchainImageIndexes.Resize(m_renderWindows.GetSize());
@@ -1092,7 +1092,7 @@ void CVkRenderContext::Frame( float fDeltaTime )
stPresentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
stPresentInfo.swapchainCount = swapchains.GetSize();
stPresentInfo.pSwapchains = swapchains.GetData();
stPresentInfo.pImageIndices = uImageIndexes.GetData();
stPresentInfo.pImageIndices = uSwapchainImageIndexes.GetData();
vkQueuePresentKHR(s_vkPresentQueue, &stPresentInfo);
vkDeviceWaitIdle(s_vkDevice);
+3 -3
View File
@@ -298,9 +298,9 @@ void CVkShaderLinker::Build()
m_out.m_data = spv.data;
m_out.m_size = spv.count;
IFileHandle *ph = filesystem->Open("a.txt", FILEMODE_WRITE);
filesystem->Write(ph, spv.data, spv.count*4);
filesystem->Close(ph);
//IFileHandle *ph = filesystem->Open("a.txt", FILEMODE_WRITE);
//filesystem->Write(ph, spv.data, spv.count*4);
//filesystem->Close(ph);
mspv_array_destroy(spv);
+13 -1
View File
@@ -70,6 +70,7 @@ void CVkShader::Build()
VkGraphicsPipelineCreateInfo createInfo = {};
CUtlVector<VkPipelineShaderStageCreateInfo> stages = {};
CUtlVector<VkShaderModuleCreateInfo> modules = {};
CUtlVector<VkShaderModule> sms = {};
VkPipelineVertexInputStateCreateInfo vertexInput = {};
VkPipelineInputAssemblyStateCreateInfo inputAssembly = {};
VkPipelineDynamicStateCreateInfo dynamicState = {};
@@ -91,6 +92,7 @@ void CVkShader::Build()
// TODO: Filter by vulkan shaders at some points
stages.Resize(m_shader.m_objects.GetSize());
modules.Resize(m_shader.m_objects.GetSize());
sms.Resize(m_shader.m_objects.GetSize());
for ( int i = 0; i < m_shader.m_objects.GetSize(); i++ )
{
VulkanInputMetaData_t *pMetaData = (VulkanInputMetaData_t*)m_shader.GetLumpPtr(m_shader.m_objects[i].m_nMetadataLump);
@@ -127,11 +129,21 @@ void CVkShader::Build()
bindings[stDescriptor.uSet].AppendTail(bind);
m_bindings.AppendTail(stDescriptor);
}
modules[i] = {};
modules[i].sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
modules[i].pCode = (uint32_t*)m_shader.GetLumpPtr(m_shader.m_objects[i].m_nDataLump);
modules[i].codeSize = m_shader.GetLumpSize(m_shader.m_objects[i].m_nDataLump);
if (!g_vkAvailableExtensions.bIsSupported_VK_KHR_MAINTENANCE_5)
{
VkResult r = vkCreateShaderModule(m_hDevice, &modules[i], NULL, &sms[i]);
VULKAN_RESULT_PRINT(r, vkCreateShaderModule);
}
stages[i] = {};
stages[i].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
stages[i].pNext = &modules[i];
if (g_vkAvailableExtensions.bIsSupported_VK_KHR_MAINTENANCE_5)
stages[i].pNext = &modules[i];
else
stages[i].module = sms[i];
stages[i].pName = "main";
stages[i].stage = VulkanGetShaderStage(m_shader.m_objects[i].m_eStage);
}
+2
View File
@@ -22,5 +22,7 @@ public:
};
#define ENGINE_BRIDGE_INTERFACE_VERSION "EngineBridge001"
#define CLIENT_ENGINE_BRIDGE_INTERFACE_VERSION "ClientEngineBridge001"
#define SERVER_ENGINE_BRIDGE_INTERFACE_VERSION "ServerEngineBridge001"
#endif
+13 -4
View File
@@ -48,10 +48,18 @@ DECLARE_BUILD_STAGE(rapier)
};
cProject.bFPIC = true;
LinkProject_t linkProject = ccompiler->Compile(&cProject);
linkProject.linkType = ELINK_DYNAMIC_LIBRARY;
linkProject.objects.AppendTail({rapier_lib});
linkProject.objects.AppendTail({GET_PROJECT_OBJECT(tier1, "tier1")});
linkProject.libraryObjects.AppendTail(GET_PROJECT_OBJECT(tier0, "tier0"));
if ( GET_PROJECT_VALUE(config, "static") == "true" )
{
linkProject.linkType = ELINK_STATIC_LIBRARY;
}
else
{
linkProject.linkType = ELINK_DYNAMIC_LIBRARY;
linkProject.objects.AppendTail({rapier_lib});
linkProject.objects.AppendTail({GET_PROJECT_OBJECT(tier1, "tier1")});
linkProject.libraryObjects.AppendTail(GET_PROJECT_OBJECT(tier0, "tier0"));
}
if (linkProject.m_target.kernel & TARGET_KERNEL_WINDOWS_DEVICES)
{
@@ -73,6 +81,7 @@ DECLARE_BUILD_STAGE(rapier)
CUtlString sz_libRapierPhysics = linker->Link(&linkProject);
ADD_OUTPUT_OBJECT("physics", sz_libRapierPhysics);
ADD_OUTPUT_OBJECT("rapier_static", rapier_lib);
return 0;
-1
View File
@@ -94,7 +94,6 @@ public:
virtual CastResult_t ShapeCast( HShape hShape, Quat vOrientation, Vector vBegin, Vector vEnd, fnCheckCast check ) override
{
return CRapierPhysicsWorld_ShapeCast(m_pWorld, (RapierShape_t*)hShape, vOrientation, vBegin, vEnd, (Option_checkCastFn){check} );
}