mirror of
				https://github.com/GayPizzaSpecifications/pork.git
				synced 2025-11-03 17:39:38 +00:00 
			
		
		
		
	examples: simple game of life impl using SDL2 thru ffi & native java collections
This commit is contained in:
		
							
								
								
									
										89
									
								
								examples/gameoflife/SDL2.pork
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								examples/gameoflife/SDL2.pork
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,89 @@
 | 
				
			|||||||
 | 
					/* Just enough SDL2 to run game of life */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SDL.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export let SDL_INIT_VIDEO = 32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export func SDL_Init(flags)
 | 
				
			||||||
 | 
					  native ffi "SDL2:SDL_Init:int:unsigned int"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export func SDL_Quit()
 | 
				
			||||||
 | 
					  native ffi "SDL2:SDL_Quit:void"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SDL_video.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export let SDL_WINDOW_ALLOW_HIGHDPI = 8192
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export let SDL_WINDOWPOS_UNDEFINED_MASK = 536805376
 | 
				
			||||||
 | 
					export func SDL_WINDOWPOS_UNDEFINED_DISPLAY(x) { SDL_WINDOWPOS_UNDEFINED_MASK | x }
 | 
				
			||||||
 | 
					export let SDL_WINDOWPOS_UNDEFINED = SDL_WINDOWPOS_UNDEFINED_DISPLAY(0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export let SDL_WINDOWPOS_CENTERED_MASK = 805240832
 | 
				
			||||||
 | 
					export func SDL_WINDOWPOS_CENTERED_DISPLAY(x) { SDL_WINDOWPOS_CENTERED_MASK | x }
 | 
				
			||||||
 | 
					export let SDL_WINDOWPOS_CENTERED = SDL_WINDOWPOS_CENTERED_DISPLAY(0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export func SDL_CreateWindow(title, x, y, w, h, flags)
 | 
				
			||||||
 | 
					  native ffi "SDL2:SDL_CreateWindow:void*:char*,int,int,int,int,unsigned int"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export func SDL_DestroyWindow(window)
 | 
				
			||||||
 | 
					  native ffi "SDL2:SDL_DestroyWindow:void:void*"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SDL_event.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export func SDL_PumpEvents()
 | 
				
			||||||
 | 
					  native ffi "SDL2:SDL_PumpEvents:void"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export func SDL_WaitEvent(event)
 | 
				
			||||||
 | 
					  native ffi "SDL2:SDL_WaitEvent:int:void*"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SDL_keyboard.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export let KMOD_NONE   = 0
 | 
				
			||||||
 | 
					export let KMOD_LSHIFT = 1
 | 
				
			||||||
 | 
					export let KMOD_RSHIFT = 2
 | 
				
			||||||
 | 
					export let KMOD_LCTRL  = 64
 | 
				
			||||||
 | 
					export let KMOD_RCTRL  = 128
 | 
				
			||||||
 | 
					export let KMOD_LALT   = 256
 | 
				
			||||||
 | 
					export let KMOD_RALT   = 512
 | 
				
			||||||
 | 
					export let KMOD_LGUI   = 1024
 | 
				
			||||||
 | 
					export let KMOD_RGUI   = 2048
 | 
				
			||||||
 | 
					export let KMOD_NUM    = 4096
 | 
				
			||||||
 | 
					export let KMOD_MODE   = 16384
 | 
				
			||||||
 | 
					export let KMOD_CAPS   = 8192
 | 
				
			||||||
 | 
					export let KMOD_SCROLL = 32768
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export func SDL_GetModState()
 | 
				
			||||||
 | 
					  native ffi "SDL2:SDL_GetModState:int"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SDL_renderer.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export let SDL_RENDERER_PRESENTVSYNC = 4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export func SDL_CreateRenderer(window, index, flags)
 | 
				
			||||||
 | 
					  native ffi "SDL2:SDL_CreateRenderer:void*:void*,int,unsigned int"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export func SDL_DestroyRenderer(renderer)
 | 
				
			||||||
 | 
					  native ffi "SDL2:SDL_DestroyRenderer:void:void*"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export func SDL_RenderSetLogicalSize(renderer, w, h)
 | 
				
			||||||
 | 
					  native ffi "SDL2:SDL_RenderSetLogicalSize:int:void*,int,int"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export func SDL_RenderPresent(renderer)
 | 
				
			||||||
 | 
					  native ffi "SDL2:SDL_RenderPresent:void:void*"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export func SDL_SetRenderDrawColor(renderer, r, g, b, a)
 | 
				
			||||||
 | 
					  native ffi "SDL2:SDL_SetRenderDrawColor:int:void*,unsigned int,unsigned int,unsigned int,unsigned int"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export func SDL_RenderClear(renderer)
 | 
				
			||||||
 | 
					  native ffi "SDL2:SDL_RenderClear:int:void*"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export func SDL_RenderDrawLine(renderer, x1, y1, x2, y2)
 | 
				
			||||||
 | 
					  native ffi "SDL2:SDL_RenderDrawLine:int:void*,int,int,int,int"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SDL_hints.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export let SDL_HINT_RENDER_LOGICAL_SIZE_MODE = "SDL_RENDER_LOGICAL_SIZE_MODE"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export func SDL_SetHint(name, value)
 | 
				
			||||||
 | 
					  native ffi "SDL2:SDL_SetHint:int:char*,char*"
 | 
				
			||||||
							
								
								
									
										171
									
								
								examples/gameoflife/gameoflife.pork
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										171
									
								
								examples/gameoflife/gameoflife.pork
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,171 @@
 | 
				
			|||||||
 | 
					import local SDL2
 | 
				
			||||||
 | 
					import java java.util.List
 | 
				
			||||||
 | 
					import java java.util.ArrayList
 | 
				
			||||||
 | 
					import java java.util.Collections
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let cellSize = 16
 | 
				
			||||||
 | 
					let gridWidth  = 64
 | 
				
			||||||
 | 
					let gridHeight = 40
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func clearScreen(renderer) {
 | 
				
			||||||
 | 
					  SDL_SetRenderDrawColor(renderer, 240, 181,  84, 255)
 | 
				
			||||||
 | 
					  SDL_RenderClear(renderer)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func drawGrid(renderer) {
 | 
				
			||||||
 | 
					  let w = cellSize * gridWidth
 | 
				
			||||||
 | 
					  let h = cellSize * gridHeight
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  SDL_SetRenderDrawColor(renderer, 243, 232, 115, 255)
 | 
				
			||||||
 | 
					  var i = 1
 | 
				
			||||||
 | 
					  while i < gridWidth {
 | 
				
			||||||
 | 
					    let x = i * cellSize
 | 
				
			||||||
 | 
					    SDL_RenderDrawLine(renderer, x, 0, x, h)
 | 
				
			||||||
 | 
					    i++
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  i = 1
 | 
				
			||||||
 | 
					  while i < gridHeight {
 | 
				
			||||||
 | 
					    let y = i * cellSize
 | 
				
			||||||
 | 
					    SDL_RenderDrawLine(renderer, 0, y, w, y)
 | 
				
			||||||
 | 
					    i++
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func drawCells(renderer, cells, swap) {
 | 
				
			||||||
 | 
					  SDL_SetRenderDrawColor(renderer, 89, 145,  57, 255)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  var i = 0
 | 
				
			||||||
 | 
					  var iy = 0
 | 
				
			||||||
 | 
					  while iy < gridHeight {
 | 
				
			||||||
 | 
					    var ix = 0
 | 
				
			||||||
 | 
					    while ix < gridWidth {
 | 
				
			||||||
 | 
					      let mask = if swap { 2 } else { 1 }
 | 
				
			||||||
 | 
					      if (java_util_ArrayList_get(cells, i) & mask) == mask {
 | 
				
			||||||
 | 
					        let x = ix * cellSize
 | 
				
			||||||
 | 
					        let y = iy * cellSize
 | 
				
			||||||
 | 
					        SDL_RenderDrawLine(renderer, x, y, x + cellSize, y)
 | 
				
			||||||
 | 
					        SDL_RenderDrawLine(renderer, x, y + cellSize, x + cellSize, y + cellSize)
 | 
				
			||||||
 | 
					        SDL_RenderDrawLine(renderer, x, y, x, y + cellSize)
 | 
				
			||||||
 | 
					        SDL_RenderDrawLine(renderer, x + cellSize, y, x + cellSize, y + cellSize)
 | 
				
			||||||
 | 
					        SDL_RenderDrawLine(renderer, x, y, x + cellSize, y + cellSize)
 | 
				
			||||||
 | 
					        SDL_RenderDrawLine(renderer, x + cellSize, y, x, y + cellSize)
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      i++
 | 
				
			||||||
 | 
					      ix++
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    iy++
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func createCellGrid() {
 | 
				
			||||||
 | 
					  let numCells = gridWidth * gridHeight
 | 
				
			||||||
 | 
					  let init = java_util_Collections_nCopies(numCells, 0)
 | 
				
			||||||
 | 
					  java_util_ArrayList_new_collection(init)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func getCell(cells, swap, x, y) {
 | 
				
			||||||
 | 
					  if (x >= 0) and (y >= 0) and (x < gridWidth) and (y < gridHeight) {
 | 
				
			||||||
 | 
					    let mask = if swap { 2 } else { 1 }
 | 
				
			||||||
 | 
					    (java_util_ArrayList_get(cells, x + y * gridWidth) & mask) != 0
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    false
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func setCell(cells, swap, x, y, state) {
 | 
				
			||||||
 | 
					  if (x >= 0) and (y >= 0) and (x < gridWidth) and (y < gridHeight) {
 | 
				
			||||||
 | 
					    let mask = if swap { 2 } else { 1 }
 | 
				
			||||||
 | 
					    let idx = x + y * gridWidth
 | 
				
			||||||
 | 
					    let value = java_util_ArrayList_get(cells, idx)
 | 
				
			||||||
 | 
					    if state { java_util_ArrayList_set(cells, idx, value | mask) }
 | 
				
			||||||
 | 
					    else     { java_util_ArrayList_set(cells, idx, value & (~mask)) }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func countNeighbours(cells, swap, x, y) {
 | 
				
			||||||
 | 
					  var count = 0
 | 
				
			||||||
 | 
					  if getCell(cells, swap, x, y - 1) { count++ }
 | 
				
			||||||
 | 
					  if getCell(cells, swap, x + 1, y - 1) { count++ }
 | 
				
			||||||
 | 
					  if getCell(cells, swap, x + 1, y) { count++ }
 | 
				
			||||||
 | 
					  if getCell(cells, swap, x + 1, y + 1) { count++ }
 | 
				
			||||||
 | 
					  if getCell(cells, swap, x, y + 1) { count++ }
 | 
				
			||||||
 | 
					  if getCell(cells, swap, x - 1, y + 1) { count++ }
 | 
				
			||||||
 | 
					  if getCell(cells, swap, x - 1, y) { count++ }
 | 
				
			||||||
 | 
					  if getCell(cells, swap, x - 1, y - 1) { count++ }
 | 
				
			||||||
 | 
					  count
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func gameOfLife(cells, swap) {
 | 
				
			||||||
 | 
					  var iy = 0
 | 
				
			||||||
 | 
					  while iy < gridHeight {
 | 
				
			||||||
 | 
					    var ix = 0
 | 
				
			||||||
 | 
					    while ix < gridWidth {
 | 
				
			||||||
 | 
					      let neighbours = countNeighbours(cells, not swap, ix, iy)
 | 
				
			||||||
 | 
					      let live = if getCell(cells, not swap, ix, iy) {
 | 
				
			||||||
 | 
					        (neighbours == 2) or (neighbours == 3)
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        neighbours == 3
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      setCell(cells, swap, ix, iy, live)
 | 
				
			||||||
 | 
					      ix++
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    iy++
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func createGosperGun(cells, swap, x, y) {
 | 
				
			||||||
 | 
					  for i in [
 | 
				
			||||||
 | 
					    [ 1, 5], [ 2, 5], [ 1, 6], [ 2, 6], [11, 5], [11, 6], [11, 7], [12, 4],
 | 
				
			||||||
 | 
					    [12, 8], [13, 3], [14, 3], [13, 9], [14, 9], [15, 6], [16, 4], [16, 8],
 | 
				
			||||||
 | 
					    [17, 5], [17, 6], [17, 7], [18, 6], [18, 6], [21, 3], [22, 3], [21, 4],
 | 
				
			||||||
 | 
					    [22, 4], [21, 5], [22, 5], [23, 2], [23, 6], [25, 1], [25, 2], [25, 6],
 | 
				
			||||||
 | 
					    [25, 7], [35, 3], [36, 3], [35, 4], [36, 4]
 | 
				
			||||||
 | 
					  ] {
 | 
				
			||||||
 | 
					    setCell(cells, false,
 | 
				
			||||||
 | 
					      x + java_util_List_get(i, 0),
 | 
				
			||||||
 | 
					      y + java_util_List_get(i, 1),
 | 
				
			||||||
 | 
					      true)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export func main() {
 | 
				
			||||||
 | 
					  SDL_Init(SDL_INIT_VIDEO)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let winWidth  = cellSize * gridWidth
 | 
				
			||||||
 | 
					  let winHeight = cellSize * gridHeight
 | 
				
			||||||
 | 
					  let window = SDL_CreateWindow(
 | 
				
			||||||
 | 
					    "Game of Swine",
 | 
				
			||||||
 | 
					    SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
 | 
				
			||||||
 | 
					    winWidth, winHeight,
 | 
				
			||||||
 | 
					    SDL_WINDOW_ALLOW_HIGHDPI)
 | 
				
			||||||
 | 
					  SDL_SetHint(SDL_HINT_RENDER_LOGICAL_SIZE_MODE, "letterbox")
 | 
				
			||||||
 | 
					  let rend = SDL_CreateRenderer(window, -1, SDL_RENDERER_PRESENTVSYNC)
 | 
				
			||||||
 | 
					  SDL_RenderSetLogicalSize(rend, winWidth, winHeight)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let cells = createCellGrid()
 | 
				
			||||||
 | 
					  createGosperGun(cells, false, 1, 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  var page = false
 | 
				
			||||||
 | 
					  var running = true
 | 
				
			||||||
 | 
					  while running {
 | 
				
			||||||
 | 
					    SDL_WaitEvent(None)
 | 
				
			||||||
 | 
					    let modifiers = SDL_GetModState()
 | 
				
			||||||
 | 
					    if (modifiers & KMOD_RSHIFT) == KMOD_RSHIFT { running = false }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    clearScreen(rend)
 | 
				
			||||||
 | 
					    drawGrid(rend)
 | 
				
			||||||
 | 
					    drawCells(rend, cells, page)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (modifiers & KMOD_LSHIFT) == KMOD_LSHIFT {
 | 
				
			||||||
 | 
					      page = not page
 | 
				
			||||||
 | 
					      gameOfLife(cells, page)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    SDL_RenderPresent(rend)
 | 
				
			||||||
 | 
					    SDL_PumpEvents()
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  SDL_DestroyRenderer(rend)
 | 
				
			||||||
 | 
					  SDL_DestroyWindow(window)
 | 
				
			||||||
 | 
					  SDL_Quit()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user