Hack for flags enums.
refactoring Made non-virtual function. Refactoring Rebase fixes Revert "Made non-virtual function." This reverts commit d7bfaa5bd970864f57daf18e46741ca72c5d4fe4. Reverted hack
This commit is contained in:
+1
-1
@@ -23,7 +23,7 @@ class StubGenerator(
|
|||||||
val excludedFunctions: Set<String>
|
val excludedFunctions: Set<String>
|
||||||
get() = configuration.excludedFunctions
|
get() = configuration.excludedFunctions
|
||||||
|
|
||||||
val keywords = setOf("object") // TODO
|
val keywords = setOf("object", "val") // TODO
|
||||||
|
|
||||||
fun String.mangleIfKeyword(): String {
|
fun String.mangleIfKeyword(): String {
|
||||||
return if (this in keywords) {
|
return if (this in keywords) {
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
./dist/bin/interop -def:sdl_test/sdl.def
|
||||||
|
./dist/bin/konanc sdl_test/tetris.kt SDL/SDL.kt -nativelibrary sdlstubs.bc -linkerArg -F -linkerArg /Library/Frameworks -linkerArg -framework -linkerArg SDL2
|
||||||
@@ -22,6 +22,9 @@ enum class PlacementResult(val linesCleared: Int = 0, val bonus: Int = 0) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val EMPTY: Byte = 0
|
val EMPTY: Byte = 0
|
||||||
|
val CELL1: Byte = 1
|
||||||
|
val CELL2: Byte = 2
|
||||||
|
val CELL3: Byte = 3
|
||||||
val BRICK: Byte = -1
|
val BRICK: Byte = -1
|
||||||
|
|
||||||
class Point(var x: Int, var y: Int)
|
class Point(var x: Int, var y: Int)
|
||||||
@@ -65,97 +68,97 @@ class PiecePosition(piece: Piece, private val origin: Point) {
|
|||||||
* We use Nintendo Rotation System, right-handed version.
|
* We use Nintendo Rotation System, right-handed version.
|
||||||
* See https://tetris.wiki/Nintendo_Rotation_System
|
* See https://tetris.wiki/Nintendo_Rotation_System
|
||||||
*/
|
*/
|
||||||
enum class Piece(private val origin_: Point, vararg val states: Field) {
|
enum class Piece(private val origin_: Point, private vararg val states: Field) {
|
||||||
T(Point(-1, -2),
|
T(Point(-1, -2),
|
||||||
arrayOf(
|
arrayOf(
|
||||||
byteArrayOf(0, 0, 0),
|
byteArrayOf(EMPTY, EMPTY, EMPTY),
|
||||||
byteArrayOf(1, 1, 1),
|
byteArrayOf(CELL1, CELL1, CELL1),
|
||||||
byteArrayOf(0, 1, 0)),
|
byteArrayOf(EMPTY, CELL1, EMPTY)),
|
||||||
arrayOf(
|
arrayOf(
|
||||||
byteArrayOf(0, 1, 0),
|
byteArrayOf(EMPTY, CELL1, EMPTY),
|
||||||
byteArrayOf(1, 1, 0),
|
byteArrayOf(CELL1, CELL1, EMPTY),
|
||||||
byteArrayOf(0, 1, 0)),
|
byteArrayOf(EMPTY, CELL1, EMPTY)),
|
||||||
arrayOf(
|
arrayOf(
|
||||||
byteArrayOf(0, 1, 0),
|
byteArrayOf(EMPTY, CELL1, EMPTY),
|
||||||
byteArrayOf(1, 1, 1),
|
byteArrayOf(CELL1, CELL1, CELL1),
|
||||||
byteArrayOf(0, 0, 0)),
|
byteArrayOf(EMPTY, EMPTY, EMPTY)),
|
||||||
arrayOf(
|
arrayOf(
|
||||||
byteArrayOf(0, 1, 0),
|
byteArrayOf(EMPTY, CELL1, EMPTY),
|
||||||
byteArrayOf(0, 1, 1),
|
byteArrayOf(EMPTY, CELL1, CELL1),
|
||||||
byteArrayOf(0, 1, 0))
|
byteArrayOf(EMPTY, CELL1, EMPTY))
|
||||||
),
|
),
|
||||||
J(Point(-1, -2),
|
J(Point(-1, -2),
|
||||||
arrayOf(
|
arrayOf(
|
||||||
byteArrayOf(0, 0, 0),
|
byteArrayOf(EMPTY, EMPTY, EMPTY),
|
||||||
byteArrayOf(2, 2, 2),
|
byteArrayOf(CELL2, CELL2, CELL2),
|
||||||
byteArrayOf(0, 0, 2)),
|
byteArrayOf(EMPTY, EMPTY, CELL2)),
|
||||||
arrayOf(
|
arrayOf(
|
||||||
byteArrayOf(0, 2, 0),
|
byteArrayOf(EMPTY, CELL2, EMPTY),
|
||||||
byteArrayOf(0, 2, 0),
|
byteArrayOf(EMPTY, CELL2, EMPTY),
|
||||||
byteArrayOf(2, 2, 0)),
|
byteArrayOf(CELL2, CELL2, EMPTY)),
|
||||||
arrayOf(
|
arrayOf(
|
||||||
byteArrayOf(2, 0, 0),
|
byteArrayOf(CELL2, EMPTY, EMPTY),
|
||||||
byteArrayOf(2, 2, 2),
|
byteArrayOf(CELL2, CELL2, CELL2),
|
||||||
byteArrayOf(0, 0, 0)),
|
byteArrayOf(EMPTY, EMPTY, EMPTY)),
|
||||||
arrayOf(
|
arrayOf(
|
||||||
byteArrayOf(0, 2, 2),
|
byteArrayOf(EMPTY, CELL2, CELL2),
|
||||||
byteArrayOf(0, 2, 0),
|
byteArrayOf(EMPTY, CELL2, EMPTY),
|
||||||
byteArrayOf(0, 2, 0))
|
byteArrayOf(EMPTY, CELL2, EMPTY))
|
||||||
),
|
),
|
||||||
Z(Point(-1, -2),
|
Z(Point(-1, -2),
|
||||||
arrayOf(
|
arrayOf(
|
||||||
byteArrayOf(0, 0, 0),
|
byteArrayOf(EMPTY, EMPTY, EMPTY),
|
||||||
byteArrayOf(3, 3, 0),
|
byteArrayOf(CELL3, CELL3, EMPTY),
|
||||||
byteArrayOf(0, 3, 3)),
|
byteArrayOf(EMPTY, CELL3, CELL3)),
|
||||||
arrayOf(
|
arrayOf(
|
||||||
byteArrayOf(0, 0, 3),
|
byteArrayOf(EMPTY, EMPTY, CELL3),
|
||||||
byteArrayOf(0, 3, 3),
|
byteArrayOf(EMPTY, CELL3, CELL3),
|
||||||
byteArrayOf(0, 3, 0))
|
byteArrayOf(EMPTY, CELL3, EMPTY))
|
||||||
),
|
),
|
||||||
O(Point(0, -2),
|
O(Point(0, -1),
|
||||||
arrayOf(
|
arrayOf(
|
||||||
byteArrayOf(1, 1),
|
byteArrayOf(CELL1, CELL1),
|
||||||
byteArrayOf(1, 1))
|
byteArrayOf(CELL1, CELL1))
|
||||||
),
|
),
|
||||||
S(Point(-1, -2),
|
S(Point(-1, -2),
|
||||||
arrayOf(
|
arrayOf(
|
||||||
byteArrayOf(0, 0, 0),
|
byteArrayOf(EMPTY, EMPTY, EMPTY),
|
||||||
byteArrayOf(0, 2, 2),
|
byteArrayOf(EMPTY, CELL2, CELL2),
|
||||||
byteArrayOf(2, 2, 0)),
|
byteArrayOf(CELL2, CELL2, EMPTY)),
|
||||||
arrayOf(
|
arrayOf(
|
||||||
byteArrayOf(0, 2, 0),
|
byteArrayOf(EMPTY, CELL2, EMPTY),
|
||||||
byteArrayOf(0, 2, 2),
|
byteArrayOf(EMPTY, CELL2, CELL2),
|
||||||
byteArrayOf(0, 0, 2))
|
byteArrayOf(EMPTY, EMPTY, CELL2))
|
||||||
),
|
),
|
||||||
L(Point(-1, -2),
|
L(Point(-1, -2),
|
||||||
arrayOf(
|
arrayOf(
|
||||||
byteArrayOf(0, 0, 0),
|
byteArrayOf(EMPTY, EMPTY, EMPTY),
|
||||||
byteArrayOf(3, 3, 3),
|
byteArrayOf(CELL3, CELL3, CELL3),
|
||||||
byteArrayOf(3, 0, 0)),
|
byteArrayOf(CELL3, EMPTY, EMPTY)),
|
||||||
arrayOf(
|
arrayOf(
|
||||||
byteArrayOf(3, 3, 0),
|
byteArrayOf(CELL3, CELL3, EMPTY),
|
||||||
byteArrayOf(0, 3, 0),
|
byteArrayOf(EMPTY, CELL3, EMPTY),
|
||||||
byteArrayOf(0, 3, 0)),
|
byteArrayOf(EMPTY, CELL3, EMPTY)),
|
||||||
arrayOf(
|
arrayOf(
|
||||||
byteArrayOf(0, 0, 3),
|
byteArrayOf(EMPTY, EMPTY, CELL3),
|
||||||
byteArrayOf(3, 3, 3),
|
byteArrayOf(CELL3, CELL3, CELL3),
|
||||||
byteArrayOf(0, 0, 0)),
|
byteArrayOf(EMPTY, EMPTY, EMPTY)),
|
||||||
arrayOf(
|
arrayOf(
|
||||||
byteArrayOf(0, 3, 0),
|
byteArrayOf(EMPTY, CELL3, EMPTY),
|
||||||
byteArrayOf(0, 3, 0),
|
byteArrayOf(EMPTY, CELL3, EMPTY),
|
||||||
byteArrayOf(0, 3, 3))
|
byteArrayOf(EMPTY, CELL3, CELL3))
|
||||||
),
|
),
|
||||||
I(Point(-2, -2),
|
I(Point(-2, -2),
|
||||||
arrayOf(
|
arrayOf(
|
||||||
byteArrayOf(0, 0, 0, 0),
|
byteArrayOf(EMPTY, EMPTY, EMPTY, EMPTY),
|
||||||
byteArrayOf(0, 0, 0, 0),
|
byteArrayOf(EMPTY, EMPTY, EMPTY, EMPTY),
|
||||||
byteArrayOf(1, 1, 1, 1),
|
byteArrayOf(CELL1, CELL1, CELL1, CELL1),
|
||||||
byteArrayOf(0, 0, 0, 0)),
|
byteArrayOf(EMPTY, EMPTY, EMPTY, EMPTY)),
|
||||||
arrayOf(
|
arrayOf(
|
||||||
byteArrayOf(0, 0, 1, 0),
|
byteArrayOf(EMPTY, EMPTY, CELL1, EMPTY),
|
||||||
byteArrayOf(0, 0, 1, 0),
|
byteArrayOf(EMPTY, EMPTY, CELL1, EMPTY),
|
||||||
byteArrayOf(0, 0, 1, 0),
|
byteArrayOf(EMPTY, EMPTY, CELL1, EMPTY),
|
||||||
byteArrayOf(0, 0, 1, 0))
|
byteArrayOf(EMPTY, EMPTY, CELL1, EMPTY))
|
||||||
);
|
);
|
||||||
|
|
||||||
val origin get() = Point(origin_.x, origin_.y)
|
val origin get() = Point(origin_.x, origin_.y)
|
||||||
@@ -448,7 +451,6 @@ class Game(width: Int, height: Int, val visualizer: GameFieldVisualizer, val use
|
|||||||
var attemptsToLock = 0
|
var attemptsToLock = 0
|
||||||
while (!gameOver) {
|
while (!gameOver) {
|
||||||
sleep(1000 / 60) // Refresh rate - 60 frames per second.
|
sleep(1000 / 60) // Refresh rate - 60 frames per second.
|
||||||
//sleep(200)
|
|
||||||
val commands = userInput.readCommands()
|
val commands = userInput.readCommands()
|
||||||
for (cmd in commands) {
|
for (cmd in commands) {
|
||||||
val success: Boolean
|
val success: Boolean
|
||||||
@@ -493,17 +495,23 @@ fun main(args: Array<String>) {
|
|||||||
SDL_main(args)
|
SDL_main(args)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun print_SDL_Error() {
|
fun get_SDL_Error() = SDL_GetError()!!.asCString().toString()
|
||||||
externals.printf(SDL_GetError()!!.rawValue)
|
|
||||||
}
|
|
||||||
|
|
||||||
class SDL_Visualizer(val width: Int, val height: Int): GameFieldVisualizer, UserInput {
|
class SDL_Visualizer(val width: Int, val height: Int): GameFieldVisualizer, UserInput {
|
||||||
private val CELL_SIZE = 20
|
private val CELL_SIZE = 20
|
||||||
|
private val COLORS = 10
|
||||||
|
private val CELLS_WIDTH = COLORS * CELL_SIZE
|
||||||
|
private val CELLS_HEIGHT = 3 * CELL_SIZE
|
||||||
private val SYMBOL_SIZE = 21
|
private val SYMBOL_SIZE = 21
|
||||||
private val INFO_MARGIN = 10
|
private val INFO_MARGIN = 10
|
||||||
private val MARGIN = 2
|
private val MARGIN = 2
|
||||||
private val BORDER_WIDTH = 18
|
private val BORDER_WIDTH = 18
|
||||||
private val INFO_SPACE_WIDTH = SYMBOL_SIZE * (2 + 8)
|
private val INFO_SPACE_WIDTH = SYMBOL_SIZE * (2 + 8)
|
||||||
|
private val LINES_LABEL_WIDTH = 104
|
||||||
|
private val SCORE_LABEL_WIDTH = 107
|
||||||
|
private val LEVEL_LABEL_WIDTH = 103
|
||||||
|
private val NEXT_LABEL_WIDTH = 85
|
||||||
|
private val TETRISES_LABEL_WIDTH = 162
|
||||||
|
|
||||||
private val field: Field = Array<ByteArray>(height) { ByteArray(width) }
|
private val field: Field = Array<ByteArray>(height) { ByteArray(width) }
|
||||||
private val nextPieceField: Field = Array<ByteArray>(4) { ByteArray(4) }
|
private val nextPieceField: Field = Array<ByteArray>(4) { ByteArray(4) }
|
||||||
@@ -516,57 +524,35 @@ class SDL_Visualizer(val width: Int, val height: Int): GameFieldVisualizer, User
|
|||||||
private val fieldHeight: Int
|
private val fieldHeight: Int
|
||||||
private val window: CPointer<SDL_Window>
|
private val window: CPointer<SDL_Window>
|
||||||
private val renderer: CPointer<SDL_Renderer>
|
private val renderer: CPointer<SDL_Renderer>
|
||||||
private val cells: CPointer<SDL_Texture>
|
private val texture: CPointer<SDL_Texture>
|
||||||
private val texts: CPointer<SDL_Texture>
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
|
if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
|
||||||
//println("SDL_Init error: ${SDL_GetError()}")
|
println("SDL_Init Error: ${get_SDL_Error()}")
|
||||||
print("SDL_CreateWindow Error: ")
|
|
||||||
print_SDL_Error()
|
|
||||||
println()
|
|
||||||
throw Error()
|
throw Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
fieldWidth = width * (CELL_SIZE + MARGIN) + MARGIN + BORDER_WIDTH * 2
|
fieldWidth = width * (CELL_SIZE + MARGIN) + MARGIN + BORDER_WIDTH * 2
|
||||||
fieldHeight = height * (CELL_SIZE + MARGIN) + MARGIN + BORDER_WIDTH * 2
|
fieldHeight = height * (CELL_SIZE + MARGIN) + MARGIN + BORDER_WIDTH * 2
|
||||||
val win = SDL_CreateWindow("Tetris", 100, 100, fieldWidth + INFO_SPACE_WIDTH,
|
val window = SDL_CreateWindow("Tetris", 100, 100, fieldWidth + INFO_SPACE_WIDTH,
|
||||||
fieldHeight, SDL_WindowFlags.SDL_WINDOW_SHOWN.value)
|
fieldHeight, SDL_WINDOW_SHOWN)
|
||||||
if (win == null) {
|
if (window == null) {
|
||||||
//println("SDL_CreateWindow Error: ${SDL_GetError()!!.asCString()}")
|
println("SDL_CreateWindow Error: ${get_SDL_Error()}")
|
||||||
print("SDL_CreateWindow Error: ")
|
|
||||||
print_SDL_Error()
|
|
||||||
println()
|
|
||||||
SDL_Quit()
|
SDL_Quit()
|
||||||
throw Error()
|
throw Error()
|
||||||
}
|
}
|
||||||
window = win
|
this.window = window
|
||||||
|
|
||||||
val ren = SDL_CreateRenderer(win, -1, (SDL_RendererFlags.SDL_RENDERER_ACCELERATED or SDL_RendererFlags.SDL_RENDERER_PRESENTVSYNC).value)
|
val renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED or SDL_RENDERER_PRESENTVSYNC)
|
||||||
if (ren == null) {
|
if (renderer == null) {
|
||||||
SDL_DestroyWindow(win)
|
SDL_DestroyWindow(window)
|
||||||
//println("SDL_CreateRenderer Error: ${SDL_GetError()!!.asCString()}")
|
println("SDL_CreateRenderer Error: ${get_SDL_Error()}")
|
||||||
println("SDL_CreateRenderer Error: ")
|
|
||||||
print_SDL_Error()
|
|
||||||
println()
|
|
||||||
SDL_Quit()
|
SDL_Quit()
|
||||||
throw Error()
|
throw Error()
|
||||||
}
|
}
|
||||||
renderer = ren
|
this.renderer = renderer
|
||||||
|
|
||||||
// TODO: merge together.
|
texture = loadImage(window, renderer, "tetris_all.bmp")
|
||||||
cells = loadImage(win, ren, "tetris_all.bmp")
|
|
||||||
texts = loadImage(win, ren, "tetris_cells_texts.bmp")
|
|
||||||
// if (SDL_SetTextureAlphaMod(tex, 63) != 0) {
|
|
||||||
// println("Unable to set alpha mod")
|
|
||||||
// print_SDL_Error()
|
|
||||||
// println()
|
|
||||||
// }
|
|
||||||
// if (SDL_SetTextureColorMod(tex, 127, 127, 127) != 0) {
|
|
||||||
// println("Unable to set color mod")
|
|
||||||
// print_SDL_Error()
|
|
||||||
// println()
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadImage(win: CPointer<SDL_Window>, ren: CPointer<SDL_Renderer>, imagePath: String): CPointer<SDL_Texture> {
|
private fun loadImage(win: CPointer<SDL_Window>, ren: CPointer<SDL_Renderer>, imagePath: String): CPointer<SDL_Texture> {
|
||||||
@@ -574,10 +560,7 @@ class SDL_Visualizer(val width: Int, val height: Int): GameFieldVisualizer, User
|
|||||||
if (bmp == null) {
|
if (bmp == null) {
|
||||||
SDL_DestroyRenderer(ren)
|
SDL_DestroyRenderer(ren)
|
||||||
SDL_DestroyWindow(win)
|
SDL_DestroyWindow(win)
|
||||||
//println("SDL_LoadBMP Error: ${SDL_GetError()!!.asCString()}")
|
println("SDL_LoadBMP_RW Error: ${get_SDL_Error()}")
|
||||||
println("SDL_LoadBMP Error: ")
|
|
||||||
print_SDL_Error()
|
|
||||||
println()
|
|
||||||
SDL_Quit()
|
SDL_Quit()
|
||||||
throw Error()
|
throw Error()
|
||||||
}
|
}
|
||||||
@@ -587,10 +570,7 @@ class SDL_Visualizer(val width: Int, val height: Int): GameFieldVisualizer, User
|
|||||||
if (tex == null) {
|
if (tex == null) {
|
||||||
SDL_DestroyRenderer(ren)
|
SDL_DestroyRenderer(ren)
|
||||||
SDL_DestroyWindow(win)
|
SDL_DestroyWindow(win)
|
||||||
//println("SDL_CreateTextureFromSurface Error: ${SDL_GetError()!!.asCString()}")
|
println("SDL_CreateTextureFromSurface Error: ${get_SDL_Error()}")
|
||||||
println("SDL_CreateTextureFromSurface Error: ")
|
|
||||||
print_SDL_Error()
|
|
||||||
println()
|
|
||||||
SDL_Quit()
|
SDL_Quit()
|
||||||
throw Error()
|
throw Error()
|
||||||
}
|
}
|
||||||
@@ -614,104 +594,182 @@ class SDL_Visualizer(val width: Int, val height: Int): GameFieldVisualizer, User
|
|||||||
|
|
||||||
override fun refresh() {
|
override fun refresh() {
|
||||||
SDL_RenderClear(renderer)
|
SDL_RenderClear(renderer)
|
||||||
drawBorder()
|
|
||||||
drawField()
|
drawField()
|
||||||
drawInfo()
|
drawInfo()
|
||||||
drawNextPiece()
|
drawNextPiece()
|
||||||
SDL_RenderPresent(renderer)
|
SDL_RenderPresent(renderer)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun drawBorder() {
|
private fun drawBorder(topLeftX: Int, topLeftY: Int, width: Int, height: Int) {
|
||||||
memScoped {
|
// Upper-left corner.
|
||||||
val rect = alloc<SDL_Rect>()
|
var srcX = CELLS_WIDTH
|
||||||
rect.w.value = fieldWidth
|
var srcY = 0
|
||||||
rect.h.value = fieldHeight
|
var destX = topLeftX
|
||||||
rect.x.value = 0
|
var destY = topLeftY
|
||||||
rect.y.value = 0
|
copyRect(srcX, srcY, destX, destY, BORDER_WIDTH + MARGIN, BORDER_WIDTH)
|
||||||
SDL_SetRenderDrawColor(renderer, -128, 0, -128, -128)
|
|
||||||
SDL_RenderFillRect(renderer, rect.ptr.reinterpret())
|
// Upper margin.
|
||||||
rect.w.value = fieldWidth - BORDER_WIDTH * 2
|
srcX += BORDER_WIDTH + MARGIN
|
||||||
rect.h.value = fieldHeight - BORDER_WIDTH * 2
|
destX += BORDER_WIDTH + MARGIN
|
||||||
rect.x.value = BORDER_WIDTH
|
for (i in 0..width - 1) {
|
||||||
rect.y.value = BORDER_WIDTH
|
copyRect(srcX, srcY, destX, destY, CELL_SIZE + MARGIN, BORDER_WIDTH)
|
||||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, -128)
|
destX += CELL_SIZE + MARGIN
|
||||||
SDL_RenderFillRect(renderer, rect.ptr.reinterpret())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Upper-right corner.
|
||||||
|
srcX += CELL_SIZE + MARGIN
|
||||||
|
copyRect(srcX, srcY, destX, destY, BORDER_WIDTH, BORDER_WIDTH + MARGIN)
|
||||||
|
|
||||||
|
// Right margin.
|
||||||
|
srcY += BORDER_WIDTH + MARGIN
|
||||||
|
destY += BORDER_WIDTH + MARGIN
|
||||||
|
for (j in 0..height - 1) {
|
||||||
|
copyRect(srcX, srcY, destX, destY, BORDER_WIDTH, CELL_SIZE + MARGIN)
|
||||||
|
destY += CELL_SIZE + MARGIN
|
||||||
|
}
|
||||||
|
|
||||||
|
// Left margin.
|
||||||
|
srcX = CELLS_WIDTH
|
||||||
|
srcY = BORDER_WIDTH
|
||||||
|
destX = topLeftX
|
||||||
|
destY = topLeftY + BORDER_WIDTH
|
||||||
|
for (j in 0..height - 1) {
|
||||||
|
copyRect(srcX, srcY, destX, destY, BORDER_WIDTH, CELL_SIZE + MARGIN)
|
||||||
|
destY += CELL_SIZE + MARGIN
|
||||||
|
}
|
||||||
|
|
||||||
|
// Left-down corner.
|
||||||
|
srcY += CELL_SIZE + MARGIN
|
||||||
|
copyRect(srcX, srcY, destX, destY, BORDER_WIDTH, BORDER_WIDTH + MARGIN)
|
||||||
|
|
||||||
|
// Down marign.
|
||||||
|
srcX += BORDER_WIDTH
|
||||||
|
srcY += MARGIN
|
||||||
|
destX += BORDER_WIDTH
|
||||||
|
destY += MARGIN
|
||||||
|
for (i in 0..width - 1) {
|
||||||
|
copyRect(srcX, srcY, destX, destY, CELL_SIZE + MARGIN, BORDER_WIDTH)
|
||||||
|
destX += CELL_SIZE + MARGIN
|
||||||
|
|
||||||
|
}
|
||||||
|
// Right-down corner.
|
||||||
|
srcX += CELL_SIZE + MARGIN
|
||||||
|
copyRect(srcX, srcY, destX, destY, BORDER_WIDTH + MARGIN, BORDER_WIDTH)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun drawField() {
|
private fun drawField() {
|
||||||
drawField(field, width, height, MARGIN + BORDER_WIDTH, MARGIN + BORDER_WIDTH)
|
drawField(field = field,
|
||||||
|
topLeftX = 0,
|
||||||
|
topLeftY = 0,
|
||||||
|
width = width,
|
||||||
|
height = height)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun drawNextPiece() {
|
private fun drawNextPiece() {
|
||||||
drawInt(103, 60 + SYMBOL_SIZE, fieldWidth + SYMBOL_SIZE, SYMBOL_SIZE * 11 + INFO_MARGIN * 6, 85, 0, 0)
|
drawInt(labelSrcX = LEVEL_LABEL_WIDTH,
|
||||||
drawField(nextPieceField, 4, 4,
|
labelSrcY = CELLS_HEIGHT + SYMBOL_SIZE,
|
||||||
fieldWidth + SYMBOL_SIZE + MARGIN + CELL_SIZE + MARGIN,
|
labelDestX = fieldWidth + SYMBOL_SIZE,
|
||||||
SYMBOL_SIZE * 12 + INFO_MARGIN * 7 + MARGIN)
|
labelDestY = getInfoY(5),
|
||||||
|
labelWidth = NEXT_LABEL_WIDTH,
|
||||||
|
totalDigits = 0,
|
||||||
|
value = 0)
|
||||||
|
drawField(field = nextPieceField,
|
||||||
|
topLeftX = fieldWidth + SYMBOL_SIZE,
|
||||||
|
topLeftY = getInfoY(6),
|
||||||
|
width = 4,
|
||||||
|
height = 4)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun drawField(f: Field, w: Int, h: Int, x: Int, y: Int) {
|
private fun drawField(field: Field, topLeftX: Int, topLeftY: Int, width: Int, height: Int) {
|
||||||
memScoped {
|
drawBorder(topLeftX = topLeftX,
|
||||||
val srcRect = alloc<SDL_Rect>()
|
topLeftY = topLeftY,
|
||||||
val destRect = alloc<SDL_Rect>()
|
width = width,
|
||||||
srcRect.w.value = CELL_SIZE
|
height = height)
|
||||||
srcRect.h.value = CELL_SIZE
|
for (i in 0..height - 1)
|
||||||
destRect.w.value = CELL_SIZE
|
for (j in 0..width - 1) {
|
||||||
destRect.h.value = CELL_SIZE
|
val cell = field[i][j].toInt()
|
||||||
for (i in 0..h - 1)
|
if (cell == 0) continue
|
||||||
for (j in 0..w - 1) {
|
copyRect(srcX = (level % COLORS) * CELL_SIZE,
|
||||||
val cell = f[i][j].toInt()
|
srcY = (3 - cell) * CELL_SIZE,
|
||||||
if (cell == 0) continue
|
destX = topLeftX + BORDER_WIDTH + MARGIN + j * (CELL_SIZE + MARGIN),
|
||||||
srcRect.x.value = (cell - 1) * CELL_SIZE
|
destY = topLeftY + BORDER_WIDTH + MARGIN + i * (CELL_SIZE + MARGIN),
|
||||||
srcRect.y.value = (level % 10) * CELL_SIZE
|
width = CELL_SIZE,
|
||||||
destRect.x.value = x + j * (CELL_SIZE + MARGIN)
|
height = CELL_SIZE)
|
||||||
destRect.y.value = y + i * (CELL_SIZE + MARGIN)
|
}
|
||||||
SDL_RenderCopy(renderer, cells, srcRect.ptr.reinterpret(), destRect.ptr.reinterpret())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun drawInfo() {
|
private fun drawInfo() {
|
||||||
drawInt(104, 60, fieldWidth + SYMBOL_SIZE, SYMBOL_SIZE, 107, 6, score)
|
drawInt(labelSrcX = LINES_LABEL_WIDTH,
|
||||||
drawInt(0, 60, fieldWidth + SYMBOL_SIZE, SYMBOL_SIZE * 3 + INFO_MARGIN, 104, 3, linesCleared)
|
labelSrcY = CELLS_HEIGHT,
|
||||||
drawInt(0, 60 + SYMBOL_SIZE, fieldWidth + SYMBOL_SIZE, SYMBOL_SIZE * 5 + INFO_MARGIN * 2, 103, 2, level)
|
labelDestX = fieldWidth + SYMBOL_SIZE,
|
||||||
drawInt(0, 60 + SYMBOL_SIZE * 2, fieldWidth + SYMBOL_SIZE, SYMBOL_SIZE * 7 + INFO_MARGIN * 3, 162, 2, tetrises)
|
labelDestY = getInfoY(0),
|
||||||
|
labelWidth = SCORE_LABEL_WIDTH,
|
||||||
|
totalDigits = 6,
|
||||||
|
value = score)
|
||||||
|
drawInt(labelSrcX = 0,
|
||||||
|
labelSrcY = CELLS_HEIGHT,
|
||||||
|
labelDestX = fieldWidth + SYMBOL_SIZE,
|
||||||
|
labelDestY = getInfoY(1),
|
||||||
|
labelWidth = LINES_LABEL_WIDTH,
|
||||||
|
totalDigits = 3,
|
||||||
|
value = linesCleared)
|
||||||
|
drawInt(labelSrcX = 0,
|
||||||
|
labelSrcY = CELLS_HEIGHT + SYMBOL_SIZE,
|
||||||
|
labelDestX = fieldWidth + SYMBOL_SIZE,
|
||||||
|
labelDestY = getInfoY(2),
|
||||||
|
labelWidth = LEVEL_LABEL_WIDTH,
|
||||||
|
totalDigits = 2,
|
||||||
|
value = level)
|
||||||
|
drawInt(labelSrcX = 0,
|
||||||
|
labelSrcY = CELLS_HEIGHT + SYMBOL_SIZE * 2,
|
||||||
|
labelDestX = fieldWidth + SYMBOL_SIZE,
|
||||||
|
labelDestY = getInfoY(3),
|
||||||
|
labelWidth = TETRISES_LABEL_WIDTH,
|
||||||
|
totalDigits = 2,
|
||||||
|
value = tetrises)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getInfoY(line: Int): Int {
|
||||||
|
return SYMBOL_SIZE * (2 * line + 1) + INFO_MARGIN * line
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun drawInt(labelSrcX: Int, labelSrcY: Int, labelDestX: Int, labelDestY: Int,
|
private fun drawInt(labelSrcX: Int, labelSrcY: Int, labelDestX: Int, labelDestY: Int,
|
||||||
labelWidth: Int, totalDigits: Int, value: Int) {
|
labelWidth: Int, totalDigits: Int, value: Int) {
|
||||||
|
copyRect(srcX = labelSrcX,
|
||||||
|
srcY = labelSrcY,
|
||||||
|
destX = labelDestX,
|
||||||
|
destY = labelDestY,
|
||||||
|
width = labelWidth,
|
||||||
|
height = SYMBOL_SIZE)
|
||||||
|
val digits = IntArray(totalDigits)
|
||||||
|
var x = value
|
||||||
|
for (i in 0..totalDigits - 1) {
|
||||||
|
digits[totalDigits - 1 - i] = x % 10
|
||||||
|
x = x / 10
|
||||||
|
}
|
||||||
|
for (i in 0..totalDigits - 1) {
|
||||||
|
copyRect(srcX = digits[i] * SYMBOL_SIZE,
|
||||||
|
srcY = CELLS_HEIGHT + 3 * SYMBOL_SIZE,
|
||||||
|
destX = labelDestX + SYMBOL_SIZE + i * SYMBOL_SIZE,
|
||||||
|
destY = labelDestY + SYMBOL_SIZE,
|
||||||
|
width = SYMBOL_SIZE,
|
||||||
|
height = SYMBOL_SIZE)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun copyRect(srcX: Int, srcY: Int, destX: Int, destY: Int, width: Int, height: Int) {
|
||||||
memScoped {
|
memScoped {
|
||||||
val srcRect = alloc<SDL_Rect>()
|
val srcRect = alloc<SDL_Rect>()
|
||||||
val destRect = alloc<SDL_Rect>()
|
val destRect = alloc<SDL_Rect>()
|
||||||
|
srcRect.w.value = width
|
||||||
srcRect.w.value = labelWidth
|
srcRect.h.value = height
|
||||||
srcRect.h.value = SYMBOL_SIZE
|
srcRect.x.value = srcX
|
||||||
srcRect.x.value = labelSrcX
|
srcRect.y.value = srcY
|
||||||
srcRect.y.value = labelSrcY
|
destRect.w.value = width
|
||||||
destRect.w.value = labelWidth
|
destRect.h.value = height
|
||||||
destRect.h.value = SYMBOL_SIZE
|
destRect.x.value = destX
|
||||||
destRect.x.value = labelDestX
|
destRect.y.value = destY
|
||||||
destRect.y.value = labelDestY
|
SDL_RenderCopy(renderer, texture, srcRect.ptr.reinterpret(), destRect.ptr.reinterpret())
|
||||||
|
|
||||||
SDL_RenderCopy(renderer, texts, srcRect.ptr.reinterpret(), destRect.ptr.reinterpret())
|
|
||||||
|
|
||||||
val digits = IntArray(totalDigits)
|
|
||||||
var x = value
|
|
||||||
for (i in 0..totalDigits - 1) {
|
|
||||||
digits[totalDigits - 1 - i] = x % 10
|
|
||||||
x = x / 10
|
|
||||||
}
|
|
||||||
srcRect.w.value = SYMBOL_SIZE
|
|
||||||
srcRect.h.value = SYMBOL_SIZE
|
|
||||||
destRect.w.value = SYMBOL_SIZE
|
|
||||||
destRect.h.value = SYMBOL_SIZE
|
|
||||||
for (i in 0..totalDigits - 1) {
|
|
||||||
srcRect.x.value = digits[i] * SYMBOL_SIZE
|
|
||||||
srcRect.y.value = 123 // TODO: constant.
|
|
||||||
destRect.x.value = labelDestX + SYMBOL_SIZE + i * SYMBOL_SIZE
|
|
||||||
destRect.y.value = labelDestY + SYMBOL_SIZE
|
|
||||||
SDL_RenderCopy(renderer, texts, srcRect.ptr.reinterpret(), destRect.ptr.reinterpret())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -741,21 +799,23 @@ class SDL_Visualizer(val width: Int, val height: Int): GameFieldVisualizer, User
|
|||||||
val event = alloc<SDL_Event>()
|
val event = alloc<SDL_Event>()
|
||||||
var currentCommands = 0
|
var currentCommands = 0
|
||||||
while (SDL_PollEvent(event.ptr.reinterpret()) != 0) {
|
while (SDL_PollEvent(event.ptr.reinterpret()) != 0) {
|
||||||
if (event.type.value == SDL_EventType.SDL_KEYDOWN.value
|
if (event.type.value == SDL_KEYDOWN
|
||||||
|| event.type.value == SDL_EventType.SDL_KEYUP.value) {
|
|| event.type.value == SDL_KEYUP) {
|
||||||
val keyboardEvent = event.ptr.reinterpret<SDL_KeyboardEvent>().pointed
|
val keyboardEvent = event.ptr.reinterpret<SDL_KeyboardEvent>().pointed
|
||||||
val scancode = when (keyboardEvent.keysym.scancode.value) {
|
val scancode = when (keyboardEvent.keysym.scancode.value) {
|
||||||
SDL_Scancode.SDL_SCANCODE_LEFT -> LEFT_PRESSED
|
SDL_SCANCODE_LEFT -> LEFT_PRESSED
|
||||||
SDL_Scancode.SDL_SCANCODE_RIGHT -> RIGHT_PRESSED
|
SDL_SCANCODE_RIGHT -> RIGHT_PRESSED
|
||||||
SDL_Scancode.SDL_SCANCODE_DOWN -> DOWN_PRESSED
|
SDL_SCANCODE_DOWN -> DOWN_PRESSED
|
||||||
SDL_Scancode.SDL_SCANCODE_Z -> Z_PRESSED
|
SDL_SCANCODE_Z -> Z_PRESSED
|
||||||
SDL_Scancode.SDL_SCANCODE_UP -> UP_PRESSED
|
SDL_SCANCODE_UP -> UP_PRESSED
|
||||||
SDL_Scancode.SDL_SCANCODE_ESCAPE -> ESC_PRESSED
|
SDL_SCANCODE_ESCAPE -> ESC_PRESSED
|
||||||
else -> 0
|
else -> 0
|
||||||
}
|
}
|
||||||
if (keyboardEvent.state.value.toInt() == SDL_PRESSED) {
|
if (keyboardEvent.state.value.toInt() == SDL_PRESSED) {
|
||||||
if (pressedKeys and scancode != 0)
|
if (pressedKeys and scancode != 0) {
|
||||||
|
// DAS - delayed auto shift: https://tetris.wiki/DAS
|
||||||
stickedKeys = stickedKeys or scancode
|
stickedKeys = stickedKeys or scancode
|
||||||
|
}
|
||||||
currentCommands = currentCommands or scancode
|
currentCommands = currentCommands or scancode
|
||||||
pressedKeys = pressedKeys or scancode
|
pressedKeys = pressedKeys or scancode
|
||||||
}
|
}
|
||||||
@@ -785,7 +845,7 @@ class SDL_Visualizer(val width: Int, val height: Int): GameFieldVisualizer, User
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun destroy() {
|
fun destroy() {
|
||||||
SDL_DestroyTexture(cells)
|
SDL_DestroyTexture(texture)
|
||||||
SDL_DestroyRenderer(renderer)
|
SDL_DestroyRenderer(renderer)
|
||||||
SDL_DestroyWindow(window)
|
SDL_DestroyWindow(window)
|
||||||
SDL_Quit()
|
SDL_Quit()
|
||||||
Executable
BIN
Binary file not shown.
|
After Width: | Height: | Size: 110 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 35 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 97 KiB |
Reference in New Issue
Block a user