Skip to content
This repository has been archived by the owner on Sep 12, 2023. It is now read-only.

Commit

Permalink
Update rendering DOOM
Browse files Browse the repository at this point in the history
  • Loading branch information
rnd-ash committed Sep 29, 2020
1 parent 7ceb186 commit 445ed0a
Show file tree
Hide file tree
Showing 46 changed files with 1,499 additions and 785 deletions.
116 changes: 116 additions & 0 deletions .idea/codeStyles/Project.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions app/src/main/java/com/rndash/mbheadunit/doom/Bsp.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.rndash.mbheadunit.doom

class Bsp {

}
56 changes: 56 additions & 0 deletions app/src/main/java/com/rndash/mbheadunit/doom/Defines.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.rndash.mbheadunit.doom

const val TICKRATE = 35
const val SCREENWIDTH = 320
const val SCREENHEIGHT = 200
const val SCREEN_MUL = 1

enum class GameState {
Level,
Intermission,
Finale,
DemoScreen
}

enum class Skill {
Baby,
Easy,
Medium,
Hard,
Nightmare
}

enum class Card {
BlueCard,
YellowCard,
RedCard,
BlueSkull,
YellowSkull,
RedSkull,
None
}

enum class AmmoType {
Clip,
Shell,
Cell,
Missile,
Unlimited // Unlimited ammo for chainsaw and fists
}

enum class PowerType {
Invulerability,
Strength,
Invisibility,
IronFeet,
AllMap,
Infrared,
}

enum class PowerDuration(val seconds: Int) {
INVULNTICS(30* TICKRATE),
INVISTICS(60 * TICKRATE),
INFRATICS(120 * TICKRATE),
IRONTICS(60 * TICKRATE)
}

169 changes: 103 additions & 66 deletions app/src/main/java/com/rndash/mbheadunit/doom/DoomSurfaceView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,41 +3,28 @@ package com.rndash.mbheadunit.doom
import android.content.Context
import android.graphics.*
import android.os.Handler
import android.view.KeyEvent
import android.view.View
import android.widget.Toast
import com.rndash.mbheadunit.R
import com.rndash.mbheadunit.doom.engine.FrameBuffer
import com.rndash.mbheadunit.doom.engine.GameEngine
import com.rndash.mbheadunit.doom.engine.ViewPort
import com.rndash.mbheadunit.car.PartyMode
import com.rndash.mbheadunit.doom.objects.Player
import com.rndash.mbheadunit.doom.objects.Scene
import com.rndash.mbheadunit.doom.objects.StatusBar
import com.rndash.mbheadunit.doom.renderer.Renderer
import com.rndash.mbheadunit.doom.wad.WadFile
import java.nio.ByteBuffer
import com.rndash.mbheadunit.nativeCan.canC.SBW_232h
import com.rndash.mbheadunit.nativeCan.canC.SID_SBW
import kotlin.math.cos
import kotlin.math.min
import kotlin.random.Random
import kotlin.math.sin
import kotlin.system.measureTimeMillis

@ExperimentalUnsignedTypes
@ExperimentalStdlibApi
class DoomSurfaceView(context: Context, private val stretchScreen: Boolean = false) : View(context) {
private val ANIMATION_DELAY_MS = 1000 / 35 // 35 FPS

class DoomSurfaceView(context: Context, stretchScreen: Boolean = false) : View(context) {
companion object {
var screenWidth: Int = 0
var screenHeight: Int = 0
const val NATIVE_WIDTH = 320
const val NATIVE_HEIGHT = 200
//const val ANIMATION_DELAY_MS = 1000 / 30 // 30 FPS
const val ANIMATION_DELAY_MS = 10 // For now lets see if we can hit 100fps
lateinit var wadFile: WadFile
var scaleWidth = 1F
var scaleHeight = 1F
var stretch = false // Integer scaling by default
fun calcSF(w: Int, h: Int) {
scaleWidth = w.toFloat() / NATIVE_WIDTH.toFloat()
scaleHeight = h.toFloat() / NATIVE_HEIGHT.toFloat()
if (!stretch) {
screenWidth = screenHeight
}
}
}

var gameEngine: GameEngine
val renderHandler = Handler()
val runner = object: Runnable {
override fun run() {
Expand All @@ -46,58 +33,108 @@ class DoomSurfaceView(context: Context, stretchScreen: Boolean = false) : View(c
}
}

companion object {
val inputThread = Thread() {
var shooting = false
while (true) {
if (SBW_232h.get_sid_sbw() != SID_SBW.EWM) {
if (!shooting) {
PartyMode.activateHazards(50)
shooting = true
}
} else {
shooting = false
}
Thread.sleep(25)
}
}
}

val w = WadFile(R.raw.doom1, context)
init {
wadFile = WadFile(R.raw.doom1, context)
wadFile.readWad()
Renderer.setPalette(w.readPalette()[0])
w.loadLevels()
w.readTextures()
runner.run()
stretch = stretchScreen
gameEngine = GameEngine(wadFile)
}

lateinit var virtualFrameBuffer: ByteArray
private var physScreenWidth = 0
private var physScreenHeight = 0
private var transformMatrix = Matrix()


private fun calcSF() {
val sfw = physScreenWidth.toFloat() / SCREENWIDTH
val sfh = physScreenHeight.toFloat() / SCREENHEIGHT
val sf = min(sfw, sfh)
if (!stretchScreen) {
// Forced to keep aspect ratio (Crisp image)
// Translate the image based on the minimum scale factor
// Then scale in both x and y by the same amount
transformMatrix.postTranslate(
(physScreenWidth - SCREENWIDTH * sf) / 2.0F,
(physScreenHeight - SCREENHEIGHT * sf) / 2.0F
)
transformMatrix.preScale(sf, sf)
} else {
// Stretch the image using a prescale matrix
transformMatrix.preScale(sfw, sfh)
}
}

lateinit var frameBufferBitmap: Bitmap
lateinit var frameBufferRect: Rect
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
screenHeight = h
screenWidth = w
calcSF(w, h)
frameBufferRect = Rect(0, 0, screenWidth, screenHeight)
physScreenHeight = h
physScreenWidth = w
calcSF()
}

/**
* Converts our 320 x 200 frame buffer used internally to something of the tablets
* native res
*/
private fun upscaleToFrameBuffer() {
frameBufferBitmap = Bitmap.createScaledBitmap(gameEngine.render(), screenWidth, screenHeight, true)
val p = Paint().apply {
color = Color.WHITE
textSize = 20F
}

var drawCalls = 0
val paint = Paint()
var fps = 0
var fbDrawCalls = 0
var lastFPSTime = System.currentTimeMillis()
private var scene = Scene(w.getLevel("E1M2"), w)
private var lastMeasureTime = 0L
private var frames = 0
private var fps = 0
val s = StatusBar(w)
override fun onDraw(canvas: Canvas) {
canvas.drawColor(Color.BLACK) // Set background to be black
// Upscale frame buffer, and display on screen
upscaleToFrameBuffer()
canvas.drawBitmap(frameBufferBitmap, null, frameBufferRect, null)
drawCalls++

measureTimeMillis {
Renderer.clear()
scene.render() // Draw scene as background
canvas.drawColor(Color.BLACK) // Set background to be black
s.render() // Draw the statusbar on top
canvas.drawBitmap(Renderer.getFrameBuffer(), transformMatrix, p)
}.let {
canvas.drawText("Frame time: $it ms", 10F, 35F, p)
}
canvas.drawText("FPS: $fps", 10F, 15F, p)

// Do FPS for debugging
paint.color = Color.WHITE
paint.textSize = 20F
canvas.drawText("FPS: $fps", 10F, 15F, paint)
canvas.drawText("$fbDrawCalls Pixel updates / sec", 10F, 40F, paint)
frames++
StatusBar.ammo ++
StatusBar.health += 0.1
if (StatusBar.ammo > 999) {
StatusBar.ammo = 0
}
if (StatusBar.health > 150) {
StatusBar.health = -50.0
}
if (System.currentTimeMillis() - lastMeasureTime >= 1000) {
fps = frames
frames = 0
lastMeasureTime = System.currentTimeMillis()
}
}

if (System.currentTimeMillis() - lastFPSTime > 1000) {
fbDrawCalls = ViewPort.pixelUpdates
ViewPort.pixelUpdates = 0
fps = drawCalls
drawCalls = 0
lastFPSTime = System.currentTimeMillis()
fun processKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
when(keyCode) {
KeyEvent.KEYCODE_W -> scene.player.fwd(10)
KeyEvent.KEYCODE_S -> scene.player.rev(10)
KeyEvent.KEYCODE_A -> scene.player.left(10)
KeyEvent.KEYCODE_D -> scene.player.right(10)
KeyEvent.KEYCODE_Q -> scene.player.apply { setAngle((getAngleDegrees()-10).toInt()) }
KeyEvent.KEYCODE_E -> scene.player.apply { setAngle((getAngleDegrees()+10).toInt()) }
}
return super.onKeyUp(keyCode, event)
}
}
Loading

0 comments on commit 445ed0a

Please sign in to comment.