Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
root = true
# noinspection EditorConfigKeyCorrectness
[*.{kt,kts}]
ktlint_code_style = android_studio
ktlint_function_naming_ignore_when_annotated_with = Composable
ktlint_standard_function-naming = disabled
ktlint_standard_filename = disabled
ktlint_standard_property-naming = disabled
ij_kotlin_allow_trailing_comma = true
ij_kotlin_allow_trailing_comma_on_call_site = true
ktlint_standard_trailing-comma-on-declaration-site = enabled
ktlint_standard_trailing-comma-on-call-site = enabled
38 changes: 32 additions & 6 deletions .github/workflows/cicd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,30 @@ permissions:
contents: write

jobs:
spotless_check:
name: Spotless Check
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up JDK 21
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '21'
cache: gradle

- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4

- name: Run Spotless Check
run: ./gradlew spotlessCheck

build_android:
name: Build Android APK
runs-on: ubuntu-latest
needs: spotless_check
steps:
- name: Checkout repository
uses: actions/checkout@v4
Expand All @@ -31,16 +52,20 @@ jobs:
- name: Build Android APK (Release)
run: ./gradlew :composeApp:assembleRelease

- name: Rename APK
run: mv composeApp/build/outputs/apk/release/composeApp-release.apk composeApp/build/outputs/apk/release/kocoboy-android.apk

- name: Upload Android APK
uses: actions/upload-artifact@v4
with:
name: android-apk
path: composeApp/build/outputs/apk/release/composeApp-release.apk
path: composeApp/build/outputs/apk/release/kocoboy-android.apk
if-no-files-found: error

build_wasm:
name: Build Wasm
runs-on: ubuntu-latest
needs: spotless_check
steps:
- name: Checkout repository
uses: actions/checkout@v4
Expand All @@ -60,13 +85,13 @@ jobs:

- name: Zip Wasm
working-directory: composeApp/build/dist/wasmJs/productionExecutable
run: zip -r wasmJs.zip .
run: zip -r kocoboy-wasm.zip .

- name: Upload Wasm Zip Artifact
uses: actions/upload-artifact@v4
with:
name: wasm-build
path: composeApp/build/dist/wasmJs/productionExecutable/wasmJs.zip
path: composeApp/build/dist/wasmJs/productionExecutable/kocoboy-wasm.zip
if-no-files-found: error

- name: Upload pages artifact
Expand Down Expand Up @@ -99,6 +124,7 @@ jobs:
- os: ubuntu-latest
ext: deb
runs-on: ${{ matrix.os }}
needs: spotless_check

steps:
- name: Checkout repository
Expand Down Expand Up @@ -141,11 +167,11 @@ jobs:
with:
repo_token: "${{ secrets.GITHUB_TOKEN }}"
automatic_release_tag: latest
prerelease: false
prerelease: true
title: "Latest Release"
files: |
android-apk/composeApp-release.apk
wasm-build/wasmJs.zip
android-apk/kocoboy-android.apk
wasm-build/kocoboy-wasm.zip
kocoboy-windows-latest.msi/*
kocoboy-macos-latest.dmg/*
kocoboy-ubuntu-latest.deb/*
23 changes: 23 additions & 0 deletions .github/workflows/pr_build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,30 @@ on:
pull_request:

jobs:
spotless_check:
name: Spotless Check
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up JDK 21
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '21'
cache: gradle

- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4

- name: Run Spotless Check
run: ./gradlew spotlessCheck

build_android:
name: Build Android APK
runs-on: ubuntu-latest
needs: spotless_check
steps:
- name: Checkout repository
uses: actions/checkout@v4
Expand All @@ -27,6 +48,7 @@ jobs:
build_wasm:
name: Build Wasm
runs-on: ubuntu-latest
needs: spotless_check
steps:
- name: Checkout repository
uses: actions/checkout@v4
Expand All @@ -53,6 +75,7 @@ jobs:
- os: macos-latest
- os: ubuntu-latest
runs-on: ${{ matrix.os }}
needs: spotless_check

steps:
- name: Checkout repository
Expand Down
4 changes: 0 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,6 @@ This is nowhere a full list of issues just some of them from a high view perspec
Yes you can, but you shouldn't. There are a lot of other more capable emulators out there.
This is just a personal project to play with Kotlin Multiplatform / Compose Multiplatform

- Why are the previews of composables on androidMain instead of commonMain?

Because @Preview annotations on Android Studio only works there.

- Why parts of the core code use unsigned while others use signed masking?

Never been a fan of Kotlin approach to unsigned. When you add limited infix bitwise operators to the mix you end on quite messy code.
Expand Down
30 changes: 25 additions & 5 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,10 +1,30 @@
import com.diffplug.gradle.spotless.SpotlessExtension
import com.diffplug.gradle.spotless.SpotlessPlugin

plugins {
// this is necessary to avoid the plugins to be loaded multiple times
// in each subproject's classloader
alias(libs.plugins.androidApplication) apply false
alias(libs.plugins.androidLibrary) apply false
alias(libs.plugins.androidKotlinMultiplatformLibrary) apply false
alias(libs.plugins.composeMultiplatform) apply false
alias(libs.plugins.composeCompiler) apply false
alias(libs.plugins.kotlinMultiplatform) apply false
alias(libs.plugins.androidKotlinMultiplatformLibrary) apply false
}
alias(libs.plugins.spotless)
}

allprojects {
apply<SpotlessPlugin>()
configure<SpotlessExtension> {
kotlin {
ktlint()
target("**/*.kt")
targetExclude("**/build/**")
trimTrailingWhitespace()
endWithNewline()
}
kotlinGradle {
ktlint()
target("**/*.gradle.kts")
trimTrailingWhitespace()
endWithNewline()
}
}
}
38 changes: 19 additions & 19 deletions composeApp/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -16,40 +16,39 @@ kotlin {
jvmTarget.set(JvmTarget.JVM_17)
}
}

listOf(
iosArm64(),
iosSimulatorArm64()
iosSimulatorArm64(),
).forEach { iosTarget ->
iosTarget.binaries.framework {
baseName = "ComposeApp"
isStatic = true
}
}

jvm("desktop")

@OptIn(ExperimentalWasmDsl::class)
wasmJs {
browser()
binaries.executable()
}

sourceSets {
val desktopMain by getting

androidMain.dependencies {
implementation(compose.preview)
implementation(libs.androidx.activity.compose)
}
commonMain.dependencies {
implementation(project(":kocoboy-core"))
implementation(compose.runtime)
implementation(compose.foundation)
implementation(compose.material3)
implementation(compose.ui)
implementation(compose.components.resources)
implementation(compose.components.uiToolingPreview)
implementation(libs.compose.runtime)
implementation(libs.compose.foundation)
implementation(libs.compose.ui)
implementation(libs.compose.material3)
implementation(libs.compose.resources)
implementation(libs.compose.preview)
implementation(libs.filekit.compose)
implementation(libs.androidx.lifecycle.viewmodel)
implementation(libs.androidx.lifecycle.runtime.compose)
Expand All @@ -62,6 +61,10 @@ kotlin {
}
}

dependencies {
debugImplementation(libs.compose.tooling)
}

android {
namespace = "io.github.bluestormdna.kocoboy"
compileSdk = libs.versions.android.compileSdk.get().toInt()
Expand All @@ -83,7 +86,7 @@ android {
isMinifyEnabled = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
"proguard-rules.pro",
)
signingConfig = signingConfigs.getByName("debug")
}
Expand All @@ -94,18 +97,15 @@ android {
}
}

dependencies {
debugImplementation(compose.uiTooling)
}

compose.desktop {
application {
mainClass = "io.github.bluestormdna.kocoboy.MainKt"

nativeDistributions {
targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)
packageName = "io.github.bluestormdna.kocoboy"
packageVersion = "1.0.0"
macOS { packageName = "kocoboy-macos" }
windows { packageName = "kocoboy-windows" }
linux { packageName = "kocoboy-linux" }
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,17 @@ class AndroidAudioPlayer : AudioPlayer {
AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA)
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.build()
.build(),
)
.setAudioFormat(
AudioFormat.Builder()
.setEncoding(encoding)
.setSampleRate(sampleRate)
.setChannelMask(channelMask)
.build()
.build(),
)
.setBufferSizeInBytes(
AudioTrack.getMinBufferSize(sampleRate, channelMask, encoding)
AudioTrack.getMinBufferSize(sampleRate, channelMask, encoding),
)
.setTransferMode(AudioTrack.MODE_STREAM)
.build()
Expand All @@ -39,4 +39,4 @@ class AndroidAudioPlayer : AudioPlayer {
audioTrack.play()
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ private val bitmap = Bitmap.createBitmap(160, 144, Bitmap.Config.ARGB_8888)
actual fun createImageBitmapFromIntArray(intArray: IntArray, width: Int, height: Int): ImageBitmap {
bitmap.setPixels(intArray, 0, 160, 0, 0, 160, 144)
return bitmap.asImageBitmap()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ class MainActivity : ComponentActivity() {
@Composable
fun AppAndroidPreview() {
App()
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package io.github.bluestormdna.kocoboy


import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.expandHorizontally
import androidx.compose.animation.fadeIn
Expand Down Expand Up @@ -50,16 +49,14 @@ import io.github.bluestormdna.kocoboy.ui.main.MainViewModel
import io.github.bluestormdna.kocoboy.ui.main.SideBar
import io.github.bluestormdna.kocoboy.ui.theme.KocoBoyTheme
import io.github.vinceglb.filekit.dialogs.compose.rememberFilePickerLauncher
import org.jetbrains.compose.ui.tooling.preview.Preview

@Composable
@Preview
fun App() {
val vm = viewModel<MainViewModel>(factory = MainViewModel.factory)

val colorTheme by vm.colorTheme.collectAsState()
val frameBuffer by vm.frame.collectAsState()
//val vps by vm.vps.collectAsState()
// val vps by vm.vps.collectAsState()
val poweredOn by vm.poweredOn.collectAsState()
val cartridgeHeader by vm.cartridgeHeader.collectAsState()

Expand All @@ -86,7 +83,7 @@ fun App() {
Box(
Modifier.fillMaxSize().padding(contentPadding),
) {
//Text(text = vps.toString())
// Text(text = vps.toString())
var showSettings by rememberSaveable { mutableStateOf(false) }

Row(
Expand Down Expand Up @@ -143,4 +140,4 @@ fun App() {
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ interface AudioPlayer {
fun play(sampleBuffer: ByteArray)
}

expect fun platformAudioPlayer(): AudioPlayer
expect fun platformAudioPlayer(): AudioPlayer
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ package io.github.bluestormdna.kocoboy

import androidx.compose.ui.graphics.ImageBitmap

expect fun createImageBitmapFromIntArray(intArray: IntArray, width: Int, height: Int): ImageBitmap
expect fun createImageBitmapFromIntArray(intArray: IntArray, width: Int, height: Int): ImageBitmap
Loading
Loading