Начало savemanager

This commit is contained in:
2025-09-05 18:38:01 +03:00
parent 8c0276c562
commit 1cd5547b04
36 changed files with 786 additions and 97 deletions
+2 -2
View File
@@ -4,10 +4,10 @@
<selectionStates>
<SelectionState runConfigName="app">
<option name="selectionMode" value="DROPDOWN" />
<DropdownSelection timestamp="2025-08-28T09:42:35.298333191Z">
<DropdownSelection timestamp="2025-08-28T12:35:54.649730307Z">
<Target type="DEFAULT_BOOT">
<handle>
<DeviceId pluginId="Default" identifier="serial=192.168.240.112:5555;connection=1b67fee5" />
<DeviceId pluginId="PhysicalDevice" identifier="serial=2B101JEGR07875" />
</handle>
</Target>
</DropdownSelection>
+1
View File
@@ -12,6 +12,7 @@
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
<option value="$PROJECT_DIR$/mpcore" />
<option value="$PROJECT_DIR$/savemanager" />
</set>
</option>
</GradleProjectSettings>
-1
View File
@@ -1,4 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
@@ -3,7 +3,6 @@ package com.ea.ironmonkey
import android.annotation.SuppressLint
import android.app.ActivityManager
import android.app.AlertDialog
import android.content.DialogInterface
import android.content.Intent
import android.content.pm.ActivityInfo
import android.content.pm.PackageManager
@@ -11,22 +10,14 @@ import android.content.res.AssetManager
import android.content.res.Configuration
import android.hardware.SensorManager
import android.media.AudioManager
import android.net.Uri
import android.opengl.GLES20
import android.os.Build
import android.os.Bundle
import android.os.Environment
import android.os.Handler
import android.os.PowerManager
import android.os.PowerManager.WakeLock
import android.os.Process
import android.provider.Settings
import android.util.DisplayMetrics
import android.view.DisplayCutout
import android.view.KeyEvent
import android.view.OrientationEventListener
import android.view.View
import android.view.ViewParent
import android.view.WindowManager
import android.view.inputmethod.InputMethodManager
import android.widget.FrameLayout
@@ -36,17 +27,13 @@ import com.ea.EAMIO.StorageDirectory
import com.ea.ironmonkey.Log.d
import com.ea.ironmonkey.Log.i
import com.ea.ironmonkey.Log.setEnable
import com.ea.ironmonkey.Log.w
import com.ea.ironmonkey.ObbHelper.getObbFileName
import com.ea.ironmonkey.domain.AssetLocationType
import com.ea.nimble.ApplicationLifecycle
import com.ea.nimble.Global
import com.google.gson.annotations.SerializedName
import nfs.mod.mpcore.MultiplayerCore.loadCore
import org.fmod.FMODAudioDevice
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.io.IOException
import java.io.InputStream
import java.util.Locale
@@ -152,7 +139,7 @@ class GameActivityMain : AppCompatActivity(), DrawFrameListener {
external fun nativeOnPause()
external fun nativeOnPhysicalKeyDown(i: Int, i2: Int)
external fun nativeOnPhysicalKeyDown(keyCode: Int, scanCode: Int)
external fun nativeOnPhysicalKeyUp(i: Int, i2: Int)
@@ -383,9 +370,6 @@ class GameActivityMain : AppCompatActivity(), DrawFrameListener {
i(TAG, "onPause state=$state")
super.onPause()
mFMODAudioDevice.stop()
/*if (mOrientationListener.canDetectOrientation()) {
mOrientationListener.disable()
}*/
gameGLSurfaceView.onPause()
ApplicationLifecycle.onActivityPause(this)
nativeOnPause()
@@ -465,23 +449,19 @@ class GameActivityMain : AppCompatActivity(), DrawFrameListener {
ApplicationLifecycle.onActivityResult(i, i2, intent, this)
}
override fun onKeyDown(i: Int, keyEvent: KeyEvent): Boolean {
super.onKeyDown(i, keyEvent)
override fun onKeyDown(keyCode: Int, keyEvent: KeyEvent): Boolean {
super.onKeyDown(keyCode, keyEvent)
if (state != 8) {
return true
}
if ((i == 4 || i == 108) && keyEvent.getRepeatCount() > 0) {
if ((keyCode == 4 || keyCode == 108) && keyEvent.repeatCount > 0) {
return true
}
val scanCode = keyEvent.getScanCode()
gameGLSurfaceView!!.queueEvent(object : Runnable {
// from class: com.ea.ironmonkey.GameActivityMain.3
// java.lang.Runnable
override fun run() {
this@GameActivityMain.nativeOnPhysicalKeyDown(i, scanCode)
val scanCode = keyEvent.scanCode
gameGLSurfaceView.queueEvent {
nativeOnPhysicalKeyDown(keyCode, scanCode)
}
})
return !IsSystemKey(i)
return !IsSystemKey(keyCode)
}
override fun onKeyUp(i: Int, keyEvent: KeyEvent): Boolean {
@@ -630,7 +610,7 @@ class GameActivityMain : AppCompatActivity(), DrawFrameListener {
override fun onDrawFrame(gl10: GL10?) {
var inputStream: InputStream?
var shouldCleanupSplash = false
Log.d("state::game", "onDrawFrame state=$state")
// Логирование изменения состояния
if (state != laststate) {
Log.d(TAG, "onDrawFrame state=$state")
@@ -639,7 +619,7 @@ class GameActivityMain : AppCompatActivity(), DrawFrameListener {
when (state) {
STATE_SPLASH -> {
splash = SplashScreen(this)
//splash = SplashScreen(this)
splash.init(
gl10,
gameRenderer.width,
@@ -650,51 +630,14 @@ class GameActivityMain : AppCompatActivity(), DrawFrameListener {
}
STATE_SPLASH_PROCESS -> {
if (splashCounter > 0) {
splashCounter--
} else {
splashTimer = System.currentTimeMillis() + 2500
if (!isAssetsReady) {
inputStream = try {
assets.open(DOWNLOAD_PROPERTIES)
} catch (e: Exception) {
null
}
if (inputStream != null) {
handler!!.postDelayed({ }, 20L)
Log.i(TAG, "state ADC start")
state = STATE_ADC_START
} else {
Log.i(TAG, "STATE_GAME_START 1")
splashTimer = System.currentTimeMillis() + 2000
state = STATE_GAME_START
}
} else {
Log.i(TAG, "STATE_GAME_START 2")
state = STATE_GAME_START
}
}
}
STATE_ADC_START -> {
Log.i(TAG, "ADC start")
// Здесь должен быть код для обработки ADC start
// state = ... // переходим в следующее состояние
}
STATE_RESTORE_CONTEXT -> {
if (splash == null) {
splash = SplashScreen(this)
splash!!.init(
gl10,
gameRenderer!!.width,
gameRenderer!!.height
)
splashDelay = System.currentTimeMillis() + 2000
}
if (splashDelay < System.currentTimeMillis() && hasWindowFocus()) {
state = if (oldState == STATE_GAME_START) {
splashTimer = System.currentTimeMillis() + 300
splashTimer = System.currentTimeMillis() + 2000
STATE_GAME_START
} else {
oldState
@@ -707,32 +650,15 @@ class GameActivityMain : AppCompatActivity(), DrawFrameListener {
isAssetsReady = true
nativeOnStart()
nativeOnResume()
gameRenderer!!.setDrawFrameListener(null)
gameRenderer.setDrawFrameListener(null)
shouldCleanupSplash = true
}
}
// Добавляем обработку остальных состояний
STATE_GOOGLE_DRM -> {
// Обработка Google DRM
}
STATE_ADC_PROCESS -> {
// Обработка ADC процесса
}
STATE_FULL_START -> {
// Обработка Full start
}
STATE_FULL_PROCESS -> {
// Обработка Full процесса
}
}
// Очистка экрана
GLES20.glClearColor(1.0f, 1.0f, 1.0f, 1.0f)
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT or GLES20.GL_DEPTH_BUFFER_BIT)
GLES20.glClearColor(1.0f, 0.0f, 0.0f, 1.0f)
//GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT or GLES20.GL_DEPTH_BUFFER_BIT)
// Отрисовка сплеш-скрина если он существует
splash.draw(
@@ -742,9 +668,9 @@ class GameActivityMain : AppCompatActivity(), DrawFrameListener {
)
// Очистка сплеш-скрина если нужно
if (shouldCleanupSplash) {
/*if (shouldCleanupSplash) {
splash.destroy(gl10)
}
}*/
}
val totalMemory: Int
@@ -48,7 +48,7 @@ class SplashScreen(private val activity: Activity) {
private var textureId = IntArray(1)
fun init(gl10: GL10?, width: Int, height: Int) {
Log.i("splash", "Я родился!")
Log.i(TAG, "init")
if (!initRenderer()) {
destroy(gl10)
return
@@ -236,6 +236,7 @@ class SplashScreen(private val activity: Activity) {
}
fun destroy(gl10: GL10?) {
Log.i(TAG, "destroy!")
if (textureId[0] != 0) {
GLES20.glDeleteTextures(1, textureId, 0)
textureId[0] = 0
+1
View File
@@ -3,4 +3,5 @@ plugins {
alias(libs.plugins.android.application) apply false
alias(libs.plugins.kotlin.android) apply false
alias(libs.plugins.android.library) apply false
alias(libs.plugins.kotlin.compose) apply false
}
+14
View File
@@ -7,6 +7,9 @@ junitVersion = "1.2.1"
espressoCore = "3.6.1"
appcompat = "1.7.0"
material = "1.12.0"
lifecycleRuntimeKtx = "2.6.1"
activityCompose = "1.8.0"
composeBom = "2024.09.00"
[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
@@ -15,9 +18,20 @@ androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "j
androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
material = { group = "com.google.android.material", name = "material", version.ref = "material" }
androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" }
androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" }
androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" }
androidx-ui = { group = "androidx.compose.ui", name = "ui" }
androidx-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" }
androidx-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }
androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" }
androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
androidx-material3 = { group = "androidx.compose.material3", name = "material3" }
[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
android-library = { id = "com.android.library", version.ref = "agp" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
+244
View File
@@ -68,6 +68,250 @@ bool is_memory_writable(void* addr, size_t size) {
return mprotect((void*)page_start, size, PROT_READ | PROT_WRITE | PROT_EXEC) == 0;
}
#include <iostream>
#include <string>
using namespace std;
// Базовый класс - Животное
class Animal {
protected:
string name;
int age;
public:
// Конструктор
Animal(const string& name, int age) : name(name), age(age) {
cout << "Animal constructor: " << name << endl;
}
// Виртуальный деструктор
virtual ~Animal() {
cout << "Animal destructor: " << name << endl;
}
// Виртуальный метод (будет переопределяться)
virtual void makeSound() const {
cout << name << " makes a generic animal sound" << endl;
}
// Не виртуальный метод (не будет переопределяться)
void sleep() const {
cout << name << " is sleeping" << endl;
}
string getName() const { return name; }
int getAge() const { return age; }
};
// Производный класс - Млекопитающее
class Mammal : public Animal {
protected:
bool hasFur;
public:
// Конструктор
Mammal(const string& name, int age, bool hasFur)
: Animal(name, age), hasFur(hasFur) {
cout << "Mammal constructor: " << name << endl;
}
// Деструктор
~Mammal() override {
cout << "Mammal destructor: " << name << endl;
}
// Переопределение метода
void makeSound() const override {
cout << name << " makes a mammal sound" << endl;
}
// Новый метод
void feedMilk() const {
cout << name << " is feeding milk" << endl;
}
};
// Производный класс - Птица
class Bird : public Animal {
protected:
double wingspan;
public:
// Конструктор
Bird(const string& name, int age, double wingspan)
: Animal(name, age), wingspan(wingspan) {
cout << "Bird constructor: " << name << endl;
}
// Деструктор
~Bird() override {
cout << "Bird destructor: " << name << endl;
}
// Переопределение метода
void makeSound() const override {
cout << name << " chirps" << endl;
}
// Новый метод
void fly() const {
cout << name << " is flying with wingspan " << wingspan << "m" << endl;
}
};
// Производный класс от Млекопитающего - Собака
class Dog : public Mammal {
private:
string breed;
public:
// Конструктор
Dog(const string& name, int age, bool hasFur, const string& breed)
: Mammal(name, age, hasFur), breed(breed) {
cout << "Dog constructor: " << name << endl;
}
// Деструктор
~Dog() override {
cout << "Dog destructor: " << name << endl;
}
// Переопределение метода
void makeSound() const override {
cout << name << " barks: Woof! Woof!" << endl;
}
// Новый метод
void fetch() const {
cout << name << " is fetching the ball" << endl;
}
};
// Производный класс от Млекопитающего - Кошка
class Cat : public Mammal {
private:
int lives;
public:
// Конструктор
Cat(const string& name, int age, bool hasFur, int lives = 9)
: Mammal(name, age, hasFur), lives(lives) {
cout << "Cat constructor: " << name << endl;
}
// Деструктор
~Cat() override {
cout << "Cat destructor: " << name << endl;
}
// Переопределение метода
void makeSound() const override {
cout << name << " meows: Meow! Meow!" << endl;
}
// Новый метод
void purr() const {
cout << name << " is purring" << endl;
}
};
// Производный класс от Птицы - Орел
class Eagle : public Bird {
private:
double visionRange;
public:
// Конструктор
Eagle(const string& name, int age, double wingspan, double visionRange)
: Bird(name, age, wingspan), visionRange(visionRange) {
cout << "Eagle constructor: " << name << endl;
}
// Деструктор
~Eagle() override {
cout << "Eagle destructor: " << name << endl;
}
// Метод НЕ переопределяется (используется версия из Bird)
// void makeSound() const override {...}
// Новый метод
void hunt() const {
cout << name << " is hunting with vision range " << visionRange << "km" << endl;
}
};
// Производный класс от Птицы - Попугай
class Parrot : public Bird {
private:
bool canTalk;
public:
// Конструктор
Parrot(const string& name, int age, double wingspan, bool canTalk)
: Bird(name, age, wingspan), canTalk(canTalk) {
cout << "Parrot constructor: " << name << endl;
}
// Деструктор
~Parrot() override {
cout << "Parrot destructor: " << name << endl;
}
// Переопределение метода
void makeSound() const override {
if (canTalk) {
cout << name << " says: Hello! Polly wants a cracker!" << endl;
} else {
cout << name << " squawks" << endl;
}
}
// Новый метод
void repeat(const string& phrase) const {
if (canTalk) {
cout << name << " repeats: " << phrase << endl;
}
}
};
// Пример использования
int main() {
cout << "=== Creating objects ===" << endl;
Dog dog("Rex", 3, true, "German Shepherd");
Cat cat("Whiskers", 2, true);
Eagle eagle("Thor", 5, 2.1, 3.5);
Parrot parrot("Polly", 1, 0.3, true);
cout << "\n=== Testing methods ===" << endl;
dog.makeSound(); // Переопределен в Dog
dog.fetch(); // Уникальный метод Dog
cat.makeSound(); // Переопределен в Cat
cat.purr(); // Уникальный метод Cat
eagle.makeSound(); // НЕ переопределен - использует версию Bird
eagle.hunt(); // Уникальный метод Eagle
parrot.makeSound(); // Переопределен в Parrot
parrot.repeat("I love C++"); // Уникальный метод Parrot
cout << "\n=== Testing polymorphism ===" << endl;
Animal* animals[] = {&dog, &cat, &eagle, &parrot};
for (Animal* animal : animals) {
animal->makeSound(); // Полиморфный вызов
animal->sleep(); // Не виртуальный метод - всегда Animal::sleep()
}
cout << "\n=== Objects going out of scope ===" << endl;
// Деструкторы будут вызваны автоматически
return 0;
}
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) {
get_libapp_base();
+1
View File
@@ -0,0 +1 @@
/build
+59
View File
@@ -0,0 +1,59 @@
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.kotlin.compose)
}
android {
namespace = "ru.megboyzz.nfsmw.save.manager"
compileSdk = 35
defaultConfig {
applicationId = "ru.megboyzz.nfsmw.save.manager"
minSdk = 24
targetSdk = 35
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
kotlinOptions {
jvmTarget = "11"
}
buildFeatures {
compose = true
}
}
dependencies {
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.lifecycle.runtime.ktx)
implementation(libs.androidx.activity.compose)
implementation(platform(libs.androidx.compose.bom))
implementation(libs.androidx.ui)
implementation(libs.androidx.ui.graphics)
implementation(libs.androidx.ui.tooling.preview)
implementation(libs.androidx.material3)
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
androidTestImplementation(platform(libs.androidx.compose.bom))
androidTestImplementation(libs.androidx.ui.test.junit4)
debugImplementation(libs.androidx.ui.tooling)
debugImplementation(libs.androidx.ui.test.manifest)
}
+21
View File
@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
@@ -0,0 +1,24 @@
package ru.megboyzz.nfsmw.save.manager
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.*
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("ru.megboyzz.nfsmw.save.manager", appContext.packageName)
}
}
+24
View File
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.NFSMostWanted">
<activity
android:name=".MainActivity"
android:exported="true"
android:label="@string/app_name"
android:theme="@style/Theme.NFSMostWanted">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
@@ -0,0 +1,23 @@
package ru.megboyzz.nfsmw.save.manager
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import ru.megboyzz.nfsmw.save.manager.ui.theme.NFSMostWantedTheme
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
}
}
}
@@ -0,0 +1,11 @@
package ru.megboyzz.nfsmw.save.manager.ui.theme
import androidx.compose.ui.graphics.Color
val Purple80 = Color(0xFFD0BCFF)
val PurpleGrey80 = Color(0xFFCCC2DC)
val Pink80 = Color(0xFFEFB8C8)
val Purple40 = Color(0xFF6650a4)
val PurpleGrey40 = Color(0xFF625b71)
val Pink40 = Color(0xFF7D5260)
@@ -0,0 +1,58 @@
package ru.megboyzz.nfsmw.save.manager.ui.theme
import android.app.Activity
import android.os.Build
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.darkColorScheme
import androidx.compose.material3.dynamicDarkColorScheme
import androidx.compose.material3.dynamicLightColorScheme
import androidx.compose.material3.lightColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalContext
private val DarkColorScheme = darkColorScheme(
primary = Purple80,
secondary = PurpleGrey80,
tertiary = Pink80
)
private val LightColorScheme = lightColorScheme(
primary = Purple40,
secondary = PurpleGrey40,
tertiary = Pink40
/* Other default colors to override
background = Color(0xFFFFFBFE),
surface = Color(0xFFFFFBFE),
onPrimary = Color.White,
onSecondary = Color.White,
onTertiary = Color.White,
onBackground = Color(0xFF1C1B1F),
onSurface = Color(0xFF1C1B1F),
*/
)
@Composable
fun NFSMostWantedTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
// Dynamic color is available on Android 12+
dynamicColor: Boolean = true,
content: @Composable () -> Unit
) {
val colorScheme = when {
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
val context = LocalContext.current
if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
}
darkTheme -> DarkColorScheme
else -> LightColorScheme
}
MaterialTheme(
colorScheme = colorScheme,
typography = Typography,
content = content
)
}
@@ -0,0 +1,34 @@
package ru.megboyzz.nfsmw.save.manager.ui.theme
import androidx.compose.material3.Typography
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.sp
// Set of Material typography styles to start with
val Typography = Typography(
bodyLarge = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.Normal,
fontSize = 16.sp,
lineHeight = 24.sp,
letterSpacing = 0.5.sp
)
/* Other default text styles to override
titleLarge = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.Normal,
fontSize = 22.sp,
lineHeight = 28.sp,
letterSpacing = 0.sp
),
labelSmall = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.Medium,
fontSize = 11.sp,
lineHeight = 16.sp,
letterSpacing = 0.5.sp
)
*/
)
@@ -0,0 +1,170 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillColor="#3DDC84"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
</vector>
@@ -0,0 +1,30 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="85.84757"
android:endY="92.4963"
android:startX="42.9492"
android:startY="49.59793"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 982 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="purple_200">#FFBB86FC</color>
<color name="purple_500">#FF6200EE</color>
<color name="purple_700">#FF3700B3</color>
<color name="teal_200">#FF03DAC5</color>
<color name="teal_700">#FF018786</color>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
</resources>
@@ -0,0 +1,3 @@
<resources>
<string name="app_name">NFSMW SaveManager</string>
</resources>
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Theme.NFSMostWanted" parent="android:Theme.Material.Light.NoActionBar" />
</resources>
@@ -0,0 +1,17 @@
package ru.megboyzz.nfsmw.save.manager
import org.junit.Test
import org.junit.Assert.*
/**
* Example local unit test, which will execute on the development machine (host).
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
class ExampleUnitTest {
@Test
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}
+1
View File
@@ -22,3 +22,4 @@ dependencyResolutionManagement {
rootProject.name = "NFS Most Wanted"
include(":app")
include(":mpcore")
include(":savemanager")