move sdl module to github.com/vlang/sdl
							parent
							
								
									7fd81d3abb
								
							
						
					
					
						commit
						3dae1cc131
					
				|  | @ -1 +0,0 @@ | |||
| main | ||||
|  | @ -1,31 +0,0 @@ | |||
| module main | ||||
| 
 | ||||
| import sdl | ||||
| 
 | ||||
| fn main() { | ||||
| 	C.SDL_Init(C.SDL_INIT_VIDEO) | ||||
| 	window := C.SDL_CreateWindow('Hello SDL2', 300, 300, 500, 300, 0) | ||||
| 	renderer := C.SDL_CreateRenderer(window, -1, C.SDL_RENDERER_ACCELERATED | C.SDL_RENDERER_PRESENTVSYNC) | ||||
| 
 | ||||
| 	mut should_close := false | ||||
| 	for { | ||||
| 		evt := SDL_Event{} | ||||
| 		for 0 < sdl.poll_event(&evt) { | ||||
| 			match int(evt.@type) { | ||||
| 				C.SDL_QUIT { should_close = true } | ||||
| 				else {} | ||||
| 			} | ||||
| 		} | ||||
| 		if should_close { | ||||
| 			break | ||||
| 		} | ||||
| 
 | ||||
| 		C.SDL_SetRenderDrawColor(renderer, 255, 55, 55, 255) | ||||
| 		C.SDL_RenderClear(renderer) | ||||
| 		C.SDL_RenderPresent(renderer) | ||||
| 	} | ||||
| 	 | ||||
| 	C.SDL_DestroyRenderer(renderer) | ||||
| 	C.SDL_DestroyWindow(window) | ||||
| 	C.SDL_Quit() | ||||
| } | ||||
|  | @ -1 +0,0 @@ | |||
| tvintris | ||||
|  | @ -1,17 +0,0 @@ | |||
| # tVintris | ||||
| 
 | ||||
| tvintris.v is a dual-player (local) version based on original source from <a href='https://github.com/vlang/v/examples/tetris'>tetris example</a> by Alex M. | ||||
| It is largely inspired by ancient game Twintris. | ||||
| -uses vlib sdl module | ||||
| 
 | ||||
|  | ||||
| 
 | ||||
| # how to run tVintris | ||||
| 
 | ||||
| `$ v run .` | ||||
| 
 | ||||
| # Credits | ||||
| 
 | ||||
| Colors, Music and Sounds inspired/ripped from amiga title Twintris (1990 nostalgia !) | ||||
| - Graphician : Svein Berge | ||||
| - Musician : Tor Bernhard Gausen (Walkman/Cryptoburners) | ||||
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 21 KiB | 
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 926 B | 
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							|  | @ -1,854 +0,0 @@ | |||
| // Copyright (c) 2019-2020 Alexander Medvednikov. All rights reserved.
 | ||||
| // Use of this source code is governed by an MIT license
 | ||||
| // that can be found in the LICENSE file.
 | ||||
| 
 | ||||
| // SDL2 port+wrapper, Twintris-like dual-game logic,
 | ||||
| // and more, by Nicolas Sauzede 2019.
 | ||||
| 
 | ||||
| module main | ||||
| 
 | ||||
| import rand | ||||
| import time | ||||
| import os | ||||
| import math | ||||
| import sdl | ||||
| import sdl.image as img | ||||
| import sdl.mixer as mix | ||||
| import sdl.ttf as ttf | ||||
| [inline] fn sdl_fill_rect(s &SDL_Surface,r &SDL_Rect,c &SDL_Color){sdl.fill_rect(s,r,c)} | ||||
| 
 | ||||
| const ( | ||||
| 	Title = 'tVintris' | ||||
| 	BASE = os.dir( os.real_path( os.executable() ) ) | ||||
| 	FontName = BASE + '/../../assets/fonts/RobotoMono-Regular.ttf' | ||||
| 	MusicName = BASE + '/sounds/TwintrisThosenine.mod' | ||||
| 	SndBlockName = BASE + '/sounds/block.wav' | ||||
| 	SndLineName = BASE + '/sounds/single.wav' | ||||
| 	SndDoubleName = BASE + '/sounds/triple.wav' | ||||
| 	VLogo = BASE + '/images/v-logo_30_30.png' | ||||
| 	BlockSize = 20 // pixels
 | ||||
| 	FieldHeight = 20 // # of blocks
 | ||||
| 	FieldWidth = 10 | ||||
| 	TetroSize = 4 | ||||
| 	WinWidth = BlockSize * FieldWidth * 3 | ||||
| 	WinHeight = BlockSize * FieldHeight | ||||
| 	TimerPeriod = 250 // ms
 | ||||
| 	TextSize = 16 | ||||
| 	AudioBufSize = 1024 | ||||
| 
 | ||||
| 	P2FIRE = C.SDLK_l | ||||
| 	P2UP = C.SDLK_UP | ||||
| 	P2DOWN = C.SDLK_DOWN | ||||
| 	P2LEFT = C.SDLK_LEFT | ||||
| 	P2RIGHT = C.SDLK_RIGHT | ||||
| 
 | ||||
| 	P1FIRE = C.SDLK_s | ||||
| 	P1UP = C.SDLK_w | ||||
| 	P1DOWN = C.SDLK_x | ||||
| 	P1LEFT = C.SDLK_a | ||||
| 	P1RIGHT = C.SDLK_d | ||||
| 
 | ||||
| 	NJOYMAX = 2 | ||||
| 	// joystick name => enter your own device name
 | ||||
| 	JOYP1NAME = 'Generic X-Box pad' | ||||
| 	// following are joystick button number
 | ||||
| 	JBP1FIRE = 1 | ||||
| 	// following are joystick hat value
 | ||||
| 	JHP1UP = 1 | ||||
| 	JHP1DOWN = 4 | ||||
| 	JHP1LEFT = 8 | ||||
| 	JHP1RIGHT = 3 | ||||
| 
 | ||||
| 	// joystick name => enter your own device name
 | ||||
| 	JOYP2NAME = 'RedOctane Guitar Hero X-plorer' | ||||
| 	// following are joystick button number
 | ||||
| 	JBP2FIRE = 0 | ||||
| 	// following are joystick hat value
 | ||||
| 	JHP2UP = 4 | ||||
| 	JHP2DOWN = 1 | ||||
| 	JHP2LEFT = 8 | ||||
| 	JHP2RIGHT = 2 | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
|   mix_version = mix.version | ||||
|   ttf_version = ttf.version | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
| 	// Tetros' 4 possible states are encoded in binaries
 | ||||
| 	BTetros = [ | ||||
| 		// 0000 0
 | ||||
| 		// 0000 0
 | ||||
| 		// 0110 6
 | ||||
| 		// 0110 6
 | ||||
| 		[66, 66, 66, 66], | ||||
| 		// 0000 0
 | ||||
| 		// 0000 0
 | ||||
| 		// 0010 2
 | ||||
| 		// 0111 7
 | ||||
| 		[27, 131, 72, 232], | ||||
| 		// 0000 0
 | ||||
| 		// 0000 0
 | ||||
| 		// 0011 3
 | ||||
| 		// 0110 6
 | ||||
| 		[36, 231, 36, 231], | ||||
| 		// 0000 0
 | ||||
| 		// 0000 0
 | ||||
| 		// 0110 6
 | ||||
| 		// 0011 3
 | ||||
| 		[63, 132, 63, 132], | ||||
| 		// 0000 0
 | ||||
| 		// 0011 3
 | ||||
| 		// 0001 1
 | ||||
| 		// 0001 1
 | ||||
| 		[311, 17, 223, 74], | ||||
| 		// 0000 0
 | ||||
| 		// 0011 3
 | ||||
| 		// 0010 2
 | ||||
| 		// 0010 2
 | ||||
| 		[322, 71, 113, 47], | ||||
| 		// Special case since 15 can't be used
 | ||||
| 		// 1111
 | ||||
| 		[1111, 9, 1111, 9], | ||||
| 	] | ||||
| 	// Each tetro has its unique color
 | ||||
| 	Colors = [ | ||||
| 		SDL_Color{byte(0), byte(0), byte(0), byte(0)},		// unused ?
 | ||||
| 		SDL_Color{byte(0), byte(0x62), byte(0xc0), byte(0)},	// quad : darkblue 0062c0
 | ||||
| 		SDL_Color{byte(0xca), byte(0x7d), byte(0x5f), byte(0)},	// tricorn : lightbrown ca7d5f
 | ||||
| 		SDL_Color{byte(0), byte(0xc1), byte(0xbf), byte(0)},	// short topright : lightblue 00c1bf
 | ||||
| 		SDL_Color{byte(0), byte(0xc1), byte(0), byte(0)},	// short topleft : lightgreen 00c100
 | ||||
| 		SDL_Color{byte(0xbf), byte(0xbe), byte(0), byte(0)},	// long topleft : yellowish bfbe00
 | ||||
| 		SDL_Color{byte(0xd1), byte(0), byte(0xbf), byte(0)},	// long topright : pink d100bf
 | ||||
| 		SDL_Color{byte(0xd1), byte(0), byte(0), byte(0)},	// longest : lightred d10000
 | ||||
| 		SDL_Color{byte(0), byte(170), byte(170), byte(0)},	// unused ?
 | ||||
| 	] | ||||
| 	// Background color
 | ||||
| 	BackgroundColor = SDL_Color{byte(0), byte(0), byte(0), byte(0)} | ||||
| 	// Foreground color
 | ||||
| 	ForegroundColor = SDL_Color{byte(0), byte(170), byte(170), byte(0)} | ||||
| 	// Text color
 | ||||
| 	TextColor = SDL_Color{byte(0xca), byte(0x7d), byte(0x5f), byte(0)} | ||||
| ) | ||||
| 
 | ||||
| // TODO: type Tetro [TetroSize]struct{ x, y int }
 | ||||
| struct Block { | ||||
| 	mut: | ||||
| 	x int | ||||
| 	y int | ||||
| } | ||||
| 
 | ||||
| enum GameState { | ||||
|         paused running gameover | ||||
| } | ||||
| 
 | ||||
| struct AudioContext { | ||||
| mut: | ||||
| 	music voidptr | ||||
| 	volume int | ||||
|         waves [3]voidptr | ||||
| } | ||||
| 
 | ||||
| struct SdlContext { | ||||
| pub mut: | ||||
| //	VIDEO
 | ||||
| 	w		int | ||||
| 	h		int | ||||
| 	window          voidptr | ||||
| 	renderer        voidptr | ||||
| 	screen          &SDL_Surface | ||||
| 	texture         voidptr | ||||
| //	AUDIO
 | ||||
| 	actx		AudioContext | ||||
| //	JOYSTICKS
 | ||||
| 	jnames		[2]string | ||||
| 	jids		[2]int | ||||
| //	V logo
 | ||||
| 	v_logo		&SDL_Surface | ||||
| 	tv_logo		voidptr | ||||
| } | ||||
| 
 | ||||
| struct Game { | ||||
| mut: | ||||
| 	// Score of the current game
 | ||||
| 	score        int | ||||
| 	// Count consecutive lines for scoring
 | ||||
| 	lines        int | ||||
| 	// State of the current game
 | ||||
| 	state    GameState | ||||
| 	// X offset of the game display
 | ||||
| 	ofs_x           int | ||||
| 	// keys
 | ||||
| 	k_fire          int | ||||
| 	k_up            int | ||||
| 	k_down          int | ||||
| 	k_left          int | ||||
| 	k_right         int | ||||
| 	// joystick ID
 | ||||
| 	joy_id           int | ||||
| 	// joystick buttons
 | ||||
| 	jb_fire          int | ||||
| 	// joystick hat values
 | ||||
| 	jh_up            int | ||||
| 	jh_down          int | ||||
| 	jh_left          int | ||||
| 	jh_right         int | ||||
| 	// game rand seed
 | ||||
| 	seed            int | ||||
| 	seed_ini            int | ||||
| 	// Position of the current tetro
 | ||||
| 	pos_x        int | ||||
| 	pos_y        int | ||||
| 	// field[y][x] contains the color of the block with (x,y) coordinates
 | ||||
| 	// "-1" border is to avoid bounds checking.
 | ||||
| 	// -1 -1 -1 -1
 | ||||
| 	// -1  0  0 -1
 | ||||
| 	// -1  0  0 -1
 | ||||
| 	// -1 -1 -1 -1
 | ||||
| 	field       [][]int | ||||
| 	// TODO: tetro Tetro
 | ||||
| 	tetro       []Block | ||||
| 	// TODO: tetros_cache []Tetro
 | ||||
| 	tetros_cache []Block | ||||
| 	// Index of the current tetro. Refers to its color.
 | ||||
| 	tetro_idx    int | ||||
| 	// Index of the next tetro. Refers to its color.
 | ||||
| 	tetro_next    int | ||||
| 	// tetro stats : buckets of drawn tetros
 | ||||
| 	tetro_stats []int | ||||
| 	// total number of drawn tetros
 | ||||
| 	tetro_total int | ||||
| 	// Index of the rotation (0-3)
 | ||||
| 	rotation_idx int | ||||
| 	// SDL2 context for drawing
 | ||||
| 	sdl             SdlContext | ||||
| 	// TTF context for font drawing
 | ||||
| 	font            voidptr | ||||
| } | ||||
| 
 | ||||
| fn (sdlc mut SdlContext) set_sdl_context(w int, h int, title string) { | ||||
| 	C.SDL_Init(C.SDL_INIT_VIDEO | C.SDL_INIT_AUDIO | C.SDL_INIT_JOYSTICK) | ||||
| 	C.atexit(C.SDL_Quit) | ||||
| 	C.TTF_Init() | ||||
| 	C.atexit(C.TTF_Quit) | ||||
| 	bpp := 32 | ||||
| 	sdl.create_window_and_renderer(w, h, 0, &sdlc.window, &sdlc.renderer) | ||||
| //	C.SDL_CreateWindowAndRenderer(w, h, 0, voidptr(&sdlc.window), voidptr(&sdlc.renderer))
 | ||||
| 	C.SDL_SetWindowTitle(sdlc.window, title.str) | ||||
| 	sdlc.w = w | ||||
| 	sdlc.h = h | ||||
| 	sdlc.screen = sdl.create_rgb_surface(0, w, h, bpp, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000) | ||||
| 	sdlc.texture = C.SDL_CreateTexture(sdlc.renderer, C.SDL_PIXELFORMAT_ARGB8888, C.SDL_TEXTUREACCESS_STREAMING, w, h) | ||||
| 
 | ||||
| 	C.Mix_Init(C.MIX_INIT_MOD) | ||||
| 	C.atexit(C.Mix_Quit) | ||||
| 	if C.Mix_OpenAudio(48000,C.MIX_DEFAULT_FORMAT,2,AudioBufSize) < 0 { | ||||
| 		println('couldn\'t open audio') | ||||
| 	} | ||||
| 	println('opening music $MusicName') | ||||
| 	sdlc.actx.music = C.Mix_LoadMUS(MusicName.str) | ||||
| 	sdlc.actx.waves[0] = C.Mix_LoadWAV(SndBlockName.str) | ||||
| 	sdlc.actx.waves[1] = C.Mix_LoadWAV(SndLineName.str) | ||||
| 	sdlc.actx.waves[2] = C.Mix_LoadWAV(SndDoubleName.str) | ||||
| 	sdlc.actx.volume = C.SDL_MIX_MAXVOLUME | ||||
| 	if C.Mix_PlayMusic(sdlc.actx.music, 1) != -1 { | ||||
| 		C.Mix_VolumeMusic(sdlc.actx.volume) | ||||
| 	} | ||||
| 	njoy := C.SDL_NumJoysticks() | ||||
| 	for i in 0..njoy { | ||||
| 		C.SDL_JoystickOpen(i) | ||||
| 		jn := tos_clone(sdl.joystick_name_for_index(i)) | ||||
| 		println('JOY NAME $jn') | ||||
| 		for j in 0..NJOYMAX { | ||||
| 			if sdlc.jnames[j] == jn { | ||||
| 				println('FOUND JOYSTICK $j $jn ID=$i') | ||||
| 				sdlc.jids[j] = i | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	flags := C.IMG_INIT_PNG | ||||
| 	imgres := img.img_init(flags) | ||||
| 	if (imgres & flags) != flags { | ||||
| 		println('error initializing image library.') | ||||
| 	} | ||||
| 	println('opening logo $VLogo') | ||||
| 	sdlc.v_logo = img.load(VLogo) | ||||
| 	if !isnil(sdlc.v_logo) { | ||||
| //		println('got v_logo=$sdlc.v_logo')
 | ||||
| 		sdlc.tv_logo = sdl.create_texture_from_surface(sdlc.renderer, sdlc.v_logo) | ||||
| //		println('got tv_logo=$sdlc.tv_logo')
 | ||||
| 	} | ||||
| 	C.SDL_JoystickEventState(C.SDL_ENABLE) | ||||
| } | ||||
| 
 | ||||
| fn main() { | ||||
| 	println('tVintris -- tribute to venerable Twintris') | ||||
| 	mut game := &Game{ font: 0 } | ||||
| 	game.sdl.jnames[0] = JOYP1NAME | ||||
| 	game.sdl.jnames[1] = JOYP2NAME | ||||
| 	game.sdl.jids[0] = -1 | ||||
| 	game.sdl.jids[1] = -1 | ||||
| 	game.sdl.set_sdl_context(WinWidth, WinHeight, Title) | ||||
| 	game.font = C.TTF_OpenFont(FontName.str, TextSize) | ||||
| 	seed := time.now().unix | ||||
| 	mut game2 := &Game{ font: 0 } | ||||
| 	game2.sdl = game.sdl | ||||
| 	game2.font = game.font | ||||
| 
 | ||||
| 	game.joy_id = game.sdl.jids[0] | ||||
| //	println('JOY1 id=${game.joy_id}')
 | ||||
| 	game2.joy_id = game.sdl.jids[1] | ||||
| //	println('JOY2 id=${game2.joy_id}')
 | ||||
| 
 | ||||
| 	// delay uses milliseconds so 1000 ms / 30 frames (30fps) roughly = 33.3333 ms/frame
 | ||||
| 	time_per_frame := 1000.0 / 30.0 | ||||
| 
 | ||||
| 	game.k_fire = P1FIRE | ||||
| 	game.k_up = P1UP | ||||
| 	game.k_down = P1DOWN | ||||
| 	game.k_left = P1LEFT | ||||
| 	game.k_right = P1RIGHT | ||||
| 	game.jb_fire = JBP1FIRE | ||||
| 	game.jh_up = JHP1UP | ||||
| 	game.jh_down = JHP1DOWN | ||||
| 	game.jh_left = JHP1LEFT | ||||
| 	game.jh_right = JHP1RIGHT | ||||
| 	game.ofs_x = 0 | ||||
| 	game.seed_ini = seed | ||||
| 	game.init_game() | ||||
| 	game.state = .running | ||||
| 	go game.run() // Run the game loop in a new thread
 | ||||
| 
 | ||||
| 	game2.k_fire = P2FIRE | ||||
| 	game2.k_up = P2UP | ||||
| 	game2.k_down = P2DOWN | ||||
| 	game2.k_left = P2LEFT | ||||
| 	game2.k_right = P2RIGHT | ||||
| 	game2.jb_fire = JBP2FIRE | ||||
| 	game2.jh_up = JHP2UP | ||||
| 	game2.jh_down = JHP2DOWN | ||||
| 	game2.jh_left = JHP2LEFT | ||||
| 	game2.jh_right = JHP2RIGHT | ||||
| 	game2.ofs_x = WinWidth * 2 / 3 | ||||
| 	game2.seed_ini = seed | ||||
| 	game2.init_game() | ||||
| 	game2.state = .running | ||||
| 	go game2.run() // Run the game loop in a new thread
 | ||||
| 
 | ||||
| 	mut g := Game{ font: 0 } | ||||
| 	mut should_close := false | ||||
| 	mut total_frame_ticks := u64(0) | ||||
| 	mut total_frames := u32(0) | ||||
| 
 | ||||
| 	for { | ||||
| 		total_frames++ | ||||
| 		start_ticks := sdl.get_perf_counter() | ||||
| 
 | ||||
| 		g1 := game | ||||
| 		g2 := game2 | ||||
| 		// here we determine which game contains most recent state
 | ||||
| 		if g1.tetro_total > g.tetro_total { | ||||
| 			g = *g1 | ||||
| 		} | ||||
| 		if g2.tetro_total > g.tetro_total { | ||||
| 			g = *g2 | ||||
| 		} | ||||
| 		g.draw_begin() | ||||
| 
 | ||||
| 		g1.draw_tetro() | ||||
| 		g1.draw_field() | ||||
| 
 | ||||
| 		g2.draw_tetro() | ||||
| 		g2.draw_field() | ||||
| 
 | ||||
| 		g.draw_middle() | ||||
| 
 | ||||
| 		g1.draw_score() | ||||
| 		g2.draw_score() | ||||
| 
 | ||||
| 		g.draw_stats() | ||||
| 
 | ||||
| 		g.draw_v_logo() | ||||
| 		g.draw_end() | ||||
| 
 | ||||
| //		game.handle_events()            // CRASHES if done in function ???
 | ||||
| 		evt := SDL_Event{} | ||||
| 		for 0 < sdl.poll_event(&evt) { | ||||
| 			match int(evt.@type) { | ||||
| 				C.SDL_QUIT { should_close = true } | ||||
| 				C.SDL_KEYDOWN { | ||||
| 					key := evt.key.keysym.sym | ||||
| 					if key == C.SDLK_ESCAPE { | ||||
| 					        should_close = true | ||||
| 					        break | ||||
| 					} | ||||
| 					game.handle_key(key) | ||||
| 					game2.handle_key(key) | ||||
| 				} | ||||
| 				C.SDL_JOYBUTTONDOWN { | ||||
| 					jb := int(evt.jbutton.button) | ||||
| 					joyid := evt.jbutton.which | ||||
| //					println('JOY BUTTON $jb $joyid')
 | ||||
| 					game.handle_jbutton(jb, joyid) | ||||
| 					game2.handle_jbutton(jb, joyid) | ||||
| 				} | ||||
| 				C.SDL_JOYHATMOTION { | ||||
| 					jh := int(evt.jhat.hat) | ||||
| 					jv := int(evt.jhat.value) | ||||
| 					joyid := evt.jhat.which | ||||
| //					println('JOY HAT $jh $jv $joyid')
 | ||||
| 					game.handle_jhat(jh, jv, joyid) | ||||
| 					game2.handle_jhat(jh, jv, joyid) | ||||
| 				} | ||||
| 				else {} | ||||
| 			} | ||||
| 		} | ||||
| 		if should_close { | ||||
| 			break | ||||
| 		} | ||||
| 		end_ticks := sdl.get_perf_counter() | ||||
| 
 | ||||
| 		total_frame_ticks += end_ticks-start_ticks | ||||
| 		elapsed_time := f64(end_ticks - start_ticks) / f64(sdl.get_perf_frequency()) | ||||
| 		// current_fps := 1.0 / elapsed_time
 | ||||
| 
 | ||||
| 		// should limit system to (1 / time_per_frame) fps
 | ||||
| 		sdl.delay(u32(math.floor(time_per_frame - elapsed_time))) | ||||
| 	} | ||||
| 	if game.font != voidptr(0) { | ||||
| 		C.TTF_CloseFont(game.font) | ||||
| 	} | ||||
| 	if game.sdl.actx.music != voidptr(0) { | ||||
| 		C.Mix_FreeMusic(game.sdl.actx.music) | ||||
| 	} | ||||
| 	C.Mix_CloseAudio() | ||||
| 	if game.sdl.actx.waves[0] != voidptr(0) { | ||||
| 		C.Mix_FreeChunk(game.sdl.actx.waves[0]) | ||||
| 	} | ||||
| 	if game.sdl.actx.waves[1] != voidptr(0) { | ||||
| 		C.Mix_FreeChunk(game.sdl.actx.waves[1]) | ||||
| 	} | ||||
| 	if game.sdl.actx.waves[2] != voidptr(0) { | ||||
| 		C.Mix_FreeChunk(game.sdl.actx.waves[2]) | ||||
| 	} | ||||
| 	if !isnil(game.sdl.tv_logo) { | ||||
| 		sdl.destroy_texture(game.sdl.tv_logo) | ||||
| 	} | ||||
| 	if !isnil(game.sdl.v_logo) { | ||||
| 		sdl.free_surface(game.sdl.v_logo) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| enum Action { | ||||
|         idle space fire | ||||
| } | ||||
| fn (game mut Game) handle_key(key int) { | ||||
| 	// global keys
 | ||||
| 	mut action := Action.idle | ||||
| 	match key { | ||||
| 		C.SDLK_SPACE { action = .space } | ||||
| 		game.k_fire { action = .fire } | ||||
| 		else {} | ||||
| 	} | ||||
| 
 | ||||
| 	if action == .space { | ||||
| 			match game.state { | ||||
| 				.running { | ||||
| 					C.Mix_PauseMusic() | ||||
| 					game.state = .paused | ||||
| 				} | ||||
| 				.paused { | ||||
| 					C.Mix_ResumeMusic() | ||||
| 					game.state = .running | ||||
| 				} | ||||
| 				else {} | ||||
| 			} | ||||
| 	} | ||||
| 
 | ||||
| 	if action == .fire { | ||||
| 			match game.state { | ||||
| 				.gameover { | ||||
| 					game.init_game() | ||||
| 					game.state = .running | ||||
| 				} | ||||
| 				else {} | ||||
| 			} | ||||
| 	} | ||||
| 	if game.state != .running { return } | ||||
| 	// keys while game is running
 | ||||
| 	match key { | ||||
| 		game.k_up { game.rotate_tetro() } | ||||
| 		game.k_left { game.move_right(-1) } | ||||
| 		game.k_right { game.move_right(1) } | ||||
| 		game.k_down { game.move_tetro() } // drop faster when the player presses <down>
 | ||||
| 		else {} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (game mut Game) handle_jbutton(jb int, joyid int) { | ||||
| 	if joyid != game.joy_id { | ||||
| 		return | ||||
| 	} | ||||
| 	// global buttons
 | ||||
| 	mut action := Action.idle | ||||
| 	match jb { | ||||
| 		game.jb_fire { action = .fire } | ||||
| 		else {} | ||||
| 	} | ||||
| 
 | ||||
| 	if action == .fire { | ||||
| 			match game.state { | ||||
| 				.gameover { | ||||
| 					game.init_game() | ||||
| 					game.state = .running | ||||
| 				} | ||||
| 				else {} | ||||
| 			} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (game mut Game) handle_jhat(jh int, jv int, joyid int) { | ||||
| 	if joyid != game.joy_id { | ||||
| 		return | ||||
| 	} | ||||
| 	if game.state != .running { return } | ||||
| //	println('testing hat values.. joyid=$joyid jh=$jh jv=$jv')
 | ||||
| 	// hat values while game is running
 | ||||
| 	match jv { | ||||
| 		game.jh_up { game.rotate_tetro() } | ||||
| 		game.jh_left { game.move_right(-1) } | ||||
| 		game.jh_right { game.move_right(1) } | ||||
| 		game.jh_down { game.move_tetro() } // drop faster when the player presses <down>
 | ||||
| 		else {} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (g mut Game) init_game() { | ||||
| 	g.score = 0 | ||||
| 	g.tetro_total = 0 | ||||
| 	g.tetro_stats = [0, 0, 0, 0, 0, 0, 0] | ||||
| 	g.parse_tetros() | ||||
| 	g.seed = g.seed_ini | ||||
| 	g.generate_tetro() | ||||
| 	g.field = [] | ||||
| 	// Generate the field, fill it with 0's, add -1's on each edge
 | ||||
| 	for i in 0..FieldHeight + 2 { | ||||
| 		mut row := [0].repeat(FieldWidth + 2) | ||||
| 		row[0] = - 1 | ||||
| 		row[FieldWidth + 1] = - 1 | ||||
| 		g.field << row | ||||
| 	} | ||||
| 	mut first_row := g.field[0] | ||||
| 	mut last_row := g.field[FieldHeight + 1] | ||||
| 	for j in 0..FieldWidth + 2 { | ||||
| 		first_row[j] = - 1 | ||||
| 		last_row[j] = - 1 | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (g mut Game) parse_tetros() { | ||||
| 	for b_tetros in BTetros { | ||||
| 		for b_tetro in b_tetros { | ||||
| 			for t in parse_binary_tetro(b_tetro) { | ||||
| 				g.tetros_cache << t | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (g mut Game) run() { | ||||
| 	for { | ||||
| 		if g.state == .running { | ||||
| 			g.move_tetro() | ||||
| 			n := g.delete_completed_lines() | ||||
| 			if n > 0 { | ||||
| 				g.lines += n | ||||
| 			} else { | ||||
| 				if g.lines > 0 { | ||||
| 					if g.lines > 1 { | ||||
| 						C.Mix_PlayChannel(0, g.sdl.actx.waves[2], 0) | ||||
| 					} else if g.lines == 1 { | ||||
| 						C.Mix_PlayChannel(0, g.sdl.actx.waves[1], 0) | ||||
| 					} | ||||
| 					g.score += 10 * g.lines * g.lines | ||||
| 					g.lines = 0 | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		time.sleep_ms(TimerPeriod)      // medium delay between game step
 | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (game mut Game) rotate_tetro() { | ||||
| 	// Rotate the tetro
 | ||||
| 	old_rotation_idx := game.rotation_idx | ||||
| 	game.rotation_idx++ | ||||
| 	if game.rotation_idx == TetroSize { | ||||
| 		game.rotation_idx = 0 | ||||
| 	} | ||||
| 	game.get_tetro() | ||||
| 	if !game.move_right(0) { | ||||
| 		game.rotation_idx = old_rotation_idx | ||||
| 		game.get_tetro() | ||||
| 	} | ||||
| 	if game.pos_x < 0 { | ||||
| 		game.pos_x = 1 | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (g mut Game) move_tetro() { | ||||
| 	// Check each block in current tetro
 | ||||
| 	for block in g.tetro { | ||||
| 		y := block.y + g.pos_y + 1 | ||||
| 		x := block.x + g.pos_x | ||||
| 		// Reached the bottom of the screen or another block?
 | ||||
| 		// TODO: if g.field[y][x] != 0
 | ||||
| 		//if g.field[y][x] != 0 {
 | ||||
| 		row := g.field[y] | ||||
| 		if row[x] != 0 { | ||||
| 			// The new tetro has no space to drop => end of the game
 | ||||
| 			if g.pos_y < 2 { | ||||
| 				g.state = .gameover | ||||
| 				g.tetro_total = 0 | ||||
| 				return | ||||
| 			} | ||||
| 			// Drop it and generate a new one
 | ||||
| 			g.drop_tetro() | ||||
| 			g.generate_tetro() | ||||
| 			C.Mix_PlayChannel(0, g.sdl.actx.waves[0], 0) | ||||
| 			return | ||||
| 		} | ||||
| 	} | ||||
| 	g.pos_y++ | ||||
| } | ||||
| 
 | ||||
| fn (g mut Game) move_right(dx int) bool { | ||||
| 	// Reached left/right edge or another tetro?
 | ||||
| 	for i in 0..TetroSize { | ||||
| 		tetro := g.tetro[i] | ||||
| 		y := tetro.y + g.pos_y | ||||
| 		x := tetro.x + g.pos_x + dx | ||||
| 		row := g.field[y] | ||||
| 		if row[x] != 0 { | ||||
| 			// Do not move
 | ||||
| 			return false | ||||
| 		} | ||||
| 	} | ||||
| 	g.pos_x += dx | ||||
| 	return true | ||||
| } | ||||
| 
 | ||||
| fn (g &Game) delete_completed_lines() int { | ||||
| 	mut n := 0 | ||||
| 	for y := FieldHeight; y >= 1; y-- { | ||||
| 		n += g.delete_completed_line(y) | ||||
| 	} | ||||
| 	return n | ||||
| } | ||||
| 
 | ||||
| fn (g &Game) delete_completed_line(y int) int { | ||||
| 	for x := 1; x <= FieldWidth; x++ { | ||||
| 		f := g.field[y] | ||||
| 		if f[x] == 0 { | ||||
| 			return 0 | ||||
| 		} | ||||
| 	} | ||||
| 	// Move everything down by 1 position
 | ||||
| 	for yy := y - 1; yy >= 1; yy-- { | ||||
| 		for x := 1; x <= FieldWidth; x++ { | ||||
| 			mut a := g.field[yy + 1] | ||||
| 			b := g.field[yy] | ||||
| 			a[x] = b[x] | ||||
| 		} | ||||
| 	} | ||||
| 	return 1 | ||||
| } | ||||
| 
 | ||||
| // Draw a rand tetro index
 | ||||
| fn (g mut Game) rand_tetro() int { | ||||
| 	cur := g.tetro_next | ||||
| 	g.tetro_next = rand.rand_r(&g.seed) | ||||
| 	g.tetro_next = g.tetro_next % BTetros.len | ||||
| 	return cur | ||||
| } | ||||
| 
 | ||||
| // Place a new tetro on top
 | ||||
| fn (g mut Game) generate_tetro() { | ||||
| 	g.pos_y = 0 | ||||
| 	g.pos_x = FieldWidth / 2 - TetroSize / 2 | ||||
| 	g.tetro_idx = g.rand_tetro() | ||||
| //	println('idx=${g.tetro_idx}')
 | ||||
| 	g.tetro_stats[g.tetro_idx]+= 2 -1 | ||||
| 	g.tetro_total++ | ||||
| 	g.rotation_idx = 0 | ||||
| 	g.get_tetro() | ||||
| } | ||||
| 
 | ||||
| // Get the right tetro from cache
 | ||||
| fn (g mut Game) get_tetro() { | ||||
| 	idx := g.tetro_idx * TetroSize * TetroSize + g.rotation_idx * TetroSize | ||||
| 	g.tetro = g.tetros_cache[idx .. idx + TetroSize] | ||||
| } | ||||
| 
 | ||||
| fn (g &Game) drop_tetro() { | ||||
| 	for i in 0..TetroSize { | ||||
| 		tetro := g.tetro[i] | ||||
| 		x := tetro.x + g.pos_x | ||||
| 		y := tetro.y + g.pos_y | ||||
| 		// Remember the color of each block
 | ||||
| 		// TODO: g.field[y][x] = g.tetro_idx + 1
 | ||||
| 		mut row := g.field[y] | ||||
| 		row[x] = g.tetro_idx + 1 | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (g &Game) draw_tetro() { | ||||
| 	for i in 0..TetroSize { | ||||
| 		tetro := g.tetro[i] | ||||
| 		g.draw_block(g.pos_y + tetro.y, g.pos_x + tetro.x, g.tetro_idx + 1) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (g &Game) draw_block(i, j, color_idx int) { | ||||
| 	rect := SDL_Rect {g.ofs_x + (j - 1) * BlockSize, (i - 1) * BlockSize, | ||||
| 		BlockSize - 1, BlockSize - 1} | ||||
| 	col := Colors[color_idx] | ||||
| 	sdl_fill_rect(g.sdl.screen, &rect, &col) | ||||
| } | ||||
| 
 | ||||
| fn (g &Game) draw_field() { | ||||
| 	for i := 1; i < FieldHeight + 1; i++ { | ||||
| 		for j := 1; j < FieldWidth + 1; j++ { | ||||
| 			f := g.field[i] | ||||
| 			if f[j] > 0 { | ||||
| 				g.draw_block(i, j, f[j]) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (g &Game) draw_v_logo() { | ||||
| 	if isnil(g.sdl.tv_logo) { | ||||
| 		return | ||||
| 	} | ||||
| 	texw := 0 | ||||
| 	texh := 0 | ||||
| 	C.SDL_QueryTexture(g.sdl.tv_logo, 0, 0, &texw, &texh) | ||||
| 	dstrect := SDL_Rect { (WinWidth / 2) - (texw / 2), 20, texw, texh } | ||||
| 	// Currently we can't seem to use sdl.render_copy when we need to pass a nil pointer (eg: srcrect to be NULL)
 | ||||
| //	sdl.render_copy(g.sdl.renderer, tv_logo, 0, &dstrect)
 | ||||
| 	C.SDL_RenderCopy(g.sdl.renderer, g.sdl.tv_logo, voidptr(0), voidptr(&dstrect)) | ||||
| } | ||||
| 
 | ||||
| fn (g &Game) draw_text(x int, y int, text string, tcol SDL_Color) { | ||||
| 	_tcol := C.SDL_Color{tcol.r, tcol.g, tcol.b, tcol.a} | ||||
| 	tsurf := C.TTF_RenderText_Solid(g.font, text.str, _tcol) | ||||
| 	ttext := C.SDL_CreateTextureFromSurface(g.sdl.renderer, tsurf) | ||||
| 	texw := 0 | ||||
| 	texh := 0 | ||||
| 	C.SDL_QueryTexture(ttext, 0, 0, &texw, &texh) | ||||
| 	dstrect := SDL_Rect { x, y, texw, texh } | ||||
| //	sdl.render_copy(g.sdl.renderer, ttext, 0, &dstrect)
 | ||||
| 	C.SDL_RenderCopy(g.sdl.renderer, ttext, voidptr(0), voidptr(&dstrect)) | ||||
| 	C.SDL_DestroyTexture(ttext) | ||||
| 	sdl.free_surface(tsurf) | ||||
| } | ||||
| 
 | ||||
| [inline] fn (g &Game) draw_ptext(x int, y int, text string, tcol SDL_Color) { | ||||
| 	g.draw_text(g.ofs_x + x, y, text, tcol) | ||||
| } | ||||
| 
 | ||||
| [live] | ||||
| fn (g &Game) draw_begin() { | ||||
| //	println('about to clear')
 | ||||
| 	C.SDL_RenderClear(g.sdl.renderer) | ||||
| 	mut rect := SDL_Rect {0,0,g.sdl.w,g.sdl.h} | ||||
| 	col := SDL_Color{byte(00), byte(00), byte(0), byte(0)} | ||||
| //	sdl_fill_rect(g.sdl.screen, &rect, BackgroundColor)
 | ||||
| 	sdl_fill_rect(g.sdl.screen, &rect, col) | ||||
| 
 | ||||
| 	rect = SDL_Rect {BlockSize * FieldWidth + 2,0,2,g.sdl.h} | ||||
| 	sdl_fill_rect(g.sdl.screen, &rect, ForegroundColor) | ||||
| 	rect = SDL_Rect {WinWidth - BlockSize * FieldWidth - 4,0,2,g.sdl.h} | ||||
| 	sdl_fill_rect(g.sdl.screen, &rect, ForegroundColor) | ||||
| 
 | ||||
| 	mut idx := 0 | ||||
| 	for st in g.tetro_stats { | ||||
| 		mut s := 10 | ||||
| 		if g.tetro_total > 0 { | ||||
| 			s += 90 * st / g.tetro_total | ||||
| 		} | ||||
| 		w := BlockSize | ||||
| 		h := s * 4 * w / 100 | ||||
| 		rect = SDL_Rect {(WinWidth - 7 * (w + 1)) / 2 + idx * (w + 1), WinHeight * 3 / 4 - h, w, h} | ||||
| 		sdl_fill_rect(g.sdl.screen, &rect, Colors[idx + 1]) | ||||
| 		idx++ | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (g &Game) draw_middle() { | ||||
| 	C.SDL_UpdateTexture(g.sdl.texture, 0, g.sdl.screen.pixels, g.sdl.screen.pitch) | ||||
| //	sdl.render_copy(g.sdl.renderer, g.sdl.texture, voidptr(0), voidptr(0))
 | ||||
| 	C.SDL_RenderCopy(g.sdl.renderer, g.sdl.texture, voidptr(0), voidptr(0)) | ||||
| } | ||||
| 
 | ||||
| fn (g &Game) draw_score() { | ||||
| 	if g.font != voidptr(0) { | ||||
| 		g.draw_ptext(1, 2, 'score: ' + g.score.str() + ' nxt=' + g.tetro_next.str(), TextColor) | ||||
| 		if g.state == .gameover { | ||||
| 			g.draw_ptext(1, WinHeight / 2 + 0 * TextSize, 'Game Over', TextColor) | ||||
| 			g.draw_ptext(1, WinHeight / 2 + 2 * TextSize, 'FIRE to restart', TextColor) | ||||
| 		} else if g.state == .paused { | ||||
| 			g.draw_ptext(1, WinHeight / 2 + 0 * TextSize, 'Game Paused', TextColor) | ||||
| 			g.draw_ptext(1, WinHeight / 2 + 2 * TextSize, 'SPACE to resume', TextColor) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (g &Game) draw_stats() { | ||||
| 	if g.font != voidptr(0) { | ||||
| 		g.draw_text(WinWidth / 3 + 10, WinHeight * 3 / 4 + 0 * TextSize, 'stats: ' + g.tetro_total.str() + ' tetros', TextColor) | ||||
| 		mut stats := '' | ||||
| 		for st in g.tetro_stats { | ||||
| 			mut s := 0 | ||||
| 			if g.tetro_total > 0 { | ||||
| 				s = 100 * st / g.tetro_total | ||||
| 			} | ||||
| 			stats += ' ' | ||||
| 			stats += s.str() | ||||
| 		} | ||||
| 		g.draw_text(WinWidth / 3 - 8, WinHeight * 3 / 4 + 2 * TextSize, stats, TextColor) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (g &Game) draw_end() { | ||||
| 	C.SDL_RenderPresent(g.sdl.renderer) | ||||
| } | ||||
| 
 | ||||
| fn parse_binary_tetro(t_ int) []Block { | ||||
| 	mut t := t_ | ||||
| 	res := [Block{}].repeat(4) | ||||
| 	mut cnt := 0 | ||||
| 	horizontal := t == 9// special case for the horizontal line
 | ||||
| 	for i := 0; i <= 3; i++ { | ||||
| 		// Get ith digit of t
 | ||||
| 		p := int(math.pow(10, 3 - i)) | ||||
| 		mut digit := t / p | ||||
| 		t %= p | ||||
| 		// Convert the digit to binary
 | ||||
| 		for j := 3; j >= 0; j-- { | ||||
| 			bin := digit % 2 | ||||
| 			digit /= 2 | ||||
| 			if bin == 1 || (horizontal && i == TetroSize - 1) { | ||||
| 				// TODO: res[cnt].x = j
 | ||||
| 				// res[cnt].y = i
 | ||||
| 				mut point := &res[cnt] | ||||
| 				point.x = j | ||||
| 				point.y = i | ||||
| 				cnt++ | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	return res | ||||
| } | ||||
|  | @ -1,21 +0,0 @@ | |||
| MIT License | ||||
| 
 | ||||
| Copyright (c) 2019 Nicolas Sauzede | ||||
| 
 | ||||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| of this software and associated documentation files (the "Software"), to deal | ||||
| in the Software without restriction, including without limitation the rights | ||||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| copies of the Software, and to permit persons to whom the Software is | ||||
| furnished to do so, subject to the following conditions: | ||||
| 
 | ||||
| The above copyright notice and this permission notice shall be included in all | ||||
| copies or substantial portions of the Software. | ||||
| 
 | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
| SOFTWARE. | ||||
|  | @ -1,60 +0,0 @@ | |||
| # sdl | ||||
| 
 | ||||
| SDL2 V module -- libSDL2 wrapper. | ||||
| 
 | ||||
| Current APIs available/tested in examples: | ||||
| - basic graphics (2D drawing) | ||||
| - [Image](image/README.md) | ||||
| - TTF font (text rendering) | ||||
| - input handling (keyboard/joystick events) | ||||
| - sounds (WAV mixing) | ||||
| - music (MOD mixing) | ||||
| - more to come.. (networking ?) | ||||
| 
 | ||||
| ## Support | ||||
| sdl is supported on: | ||||
| - Linux (major distros) | ||||
| - MacOS (brew) | ||||
| - Windows | ||||
| 
 | ||||
| ## Examples | ||||
| 
 | ||||
| [tVintris](examples/tvintris) | ||||
| 
 | ||||
|  | ||||
| 
 | ||||
| You can run the tVintris example from the V root folder like this : | ||||
| ``` | ||||
| v run vlib/sdl/examples/tvintris/tvintris.v | ||||
| ``` | ||||
| 
 | ||||
| ## Dependencies | ||||
| 
 | ||||
| ### Linux | ||||
| 
 | ||||
| #### Fedora | ||||
| `$ sudo dnf install SDL2-devel SDL2_ttf-devel SDL2_mixer-devel SDL2_image-devel` | ||||
| 
 | ||||
| #### Ubuntu | ||||
| `$ sudo apt install libsdl2-ttf-dev libsdl2-mixer-dev libsdl2-image-dev` | ||||
| 
 | ||||
| #### ClearLinux | ||||
| `$ sudo swupd bundle-add devpkg-SDL2_ttf devpkg-SDL2_mixer devpkg-SDL2_image` | ||||
| 
 | ||||
| ### MacOS | ||||
| 
 | ||||
| #### Brew | ||||
| `$ brew install sdl2 sdl2_gfx sdl2_ttf sdl2_mixer sdl2_image sdl2_net` | ||||
| 
 | ||||
| If you get no music with the above, try: | ||||
| `$ brew reinstall --build-from-source --force sdl2 sdl2_gfx sdl2_image sdl2_mixer sdl2_net sdl2_ttf webp libtiff libmodplug libogg` | ||||
| 
 | ||||
| ### Windows | ||||
| 
 | ||||
| `$ .github\workflows\windows-install-sdl.bat` | ||||
| 
 | ||||
| ## Contributions | ||||
| 
 | ||||
| - nsauzede | ||||
| - spytheman | ||||
| - adlesh | ||||
|  | @ -1,284 +0,0 @@ | |||
| module sdl | ||||
| 
 | ||||
| pub union C.SDL_Event { | ||||
| pub: | ||||
| 	@type u32 | ||||
| 	display C.SDL_DisplayEvent | ||||
| 	window C.SDL_WindowEvent | ||||
| 	key C.SDL_KeyboardEvent | ||||
| 	edit C.SDL_TextEditingEvent | ||||
| 	text C.SDL_TextInputEvent | ||||
| 	motion C.SDL_MouseMotionEvent | ||||
| 	button C.SDL_MouseButtonEvent | ||||
| 	wheel C.SDL_MouseWheelEvent | ||||
| 	jaxis C.SDL_JoyAxisEvent | ||||
| 	jball C.SDL_JoyBallEvent | ||||
| 	jhat C.SDL_JoyHatEvent | ||||
| 	jbutton C.SDL_JoyButtonEvent | ||||
| 	jdevice C.SDL_JoyDeviceEvent | ||||
| 	caxis C.SDL_ControllerAxisEvent | ||||
| 	cbutton C.SDL_ControllerButtonEvent | ||||
| 	cdevice C.SDL_ControllerDeviceEvent | ||||
| 	adevice C.SDL_AudioDeviceEvent | ||||
| 	sensor C.SDL_SensorEvent | ||||
| 	quit C.SDL_QuitEvent | ||||
| 	user C.SDL_UserEvent | ||||
| 	tfinger C.SDL_TouchFingerEvent | ||||
| 	mgesture C.SDL_MultiGestureEvent | ||||
| 	drop C.SDL_DropEvent | ||||
| 
 | ||||
| 	_pad56 [56]byte | ||||
| } | ||||
| 
 | ||||
| // individual event declarations
 | ||||
| pub struct C.SDL_DisplayEvent { | ||||
|     @type u32        /**< ::SDL_DISPLAYEVENT */ | ||||
|     timestamp u32   /**< In milliseconds, populated using SDL_GetTicks() */ | ||||
|     display u32     /**< The associated display index */ | ||||
|     event byte        /**< ::SDL_DisplayEventID */ | ||||
|     padding1 byte | ||||
|     padding2 byte | ||||
|     padding3 byte | ||||
|     data1 int       /**< event dependent data */ | ||||
| } | ||||
| 
 | ||||
| pub struct C.SDL_WindowEvent { | ||||
| pub: | ||||
| 	@type u32           /**< ::SDL_WINDOWEVENT */ | ||||
| 	timestamp u32       /**< In milliseconds, populated using SDL_GetTicks() */ | ||||
| 	windowID u32        /**< The associated window */ | ||||
| 	event byte          /**< ::SDL_WindowEventID */ | ||||
| 	padding1 byte | ||||
| 	padding2 byte | ||||
| 	padding3 byte | ||||
| 	data1 int | ||||
| 	data2 int | ||||
| } | ||||
| 
 | ||||
| pub struct C.SDL_KeyboardEvent { | ||||
| pub: | ||||
| 	@type u32   	/**< ::SDL_KEYDOWN or ::SDL_KEYUP */ | ||||
| 	timestamp u32   /**< In milliseconds, populated using SDL_GetTicks() */ | ||||
| 	windowID u32   /**< The window with keyboard focus, if any */ | ||||
| 	state byte  	/**< ::SDL_PRESSED or ::SDL_RELEASED */ | ||||
| 	repeat byte     /**< Non-zero if this is a key repeat */ | ||||
| 	padding2 byte | ||||
| 	padding3 byte | ||||
| 	keysym Keysym | ||||
| } | ||||
| 
 | ||||
| pub struct C.SDL_TextEditingEvent { | ||||
| pub: | ||||
|     @type u32                                /**< ::SDL_TEXTEDITING */ | ||||
|     timestamp u32                           /**< In milliseconds, populated using SDL_GetTicks() */ | ||||
|     windowID u32                            /**< The window with keyboard focus, if any */ | ||||
|     text [32]byte  /**< The editing text */ | ||||
|     start int                               /**< The start cursor of selected editing text */ | ||||
|     length int                              /**< The length of selected editing text */ | ||||
| } | ||||
| 
 | ||||
| pub struct C.SDL_TextInputEvent { | ||||
| pub: | ||||
|     @type u32                              /**< ::SDL_TEXTINPUT */ | ||||
|     timestamp u32                         /**< In milliseconds, populated using SDL_GetTicks() */ | ||||
|     windowID u32                          /**< The window with keyboard focus, if any */ | ||||
|     text [32]byte  /**< The input text */ | ||||
| } | ||||
| 
 | ||||
| pub struct C.SDL_MouseMotionEvent { | ||||
| pub: | ||||
|     @type u32        /**< ::SDL_MOUSEMOTION */ | ||||
|     timestamp u32   /**< In milliseconds, populated using SDL_GetTicks() */ | ||||
|     windowID u32    /**< The window with mouse focus, if any */ | ||||
|     which u32       /**< The mouse instance id, or SDL_TOUCH_MOUSEID */ | ||||
|     state u32       /**< The current button state */ | ||||
|     x int           /**< X coordinate, relative to window */ | ||||
|     y int           /**< Y coordinate, relative to window */ | ||||
|     xrel int        /**< The relative motion in the X direction */ | ||||
|     yrel int        /**< The relative motion in the Y direction */ | ||||
| } | ||||
| 
 | ||||
| pub struct C.SDL_MouseButtonEvent { | ||||
| pub: | ||||
|     @type u32        /**< ::SDL_MOUSEBUTTONDOWN or ::SDL_MOUSEBUTTONUP */ | ||||
|     timestamp u32   /**< In milliseconds, populated using SDL_GetTicks() */ | ||||
|     windowID u32    /**< The window with mouse focus, if any */ | ||||
|     which u32       /**< The mouse instance id, or SDL_TOUCH_MOUSEID */ | ||||
|     button byte       /**< The mouse button index */ | ||||
|     state byte        /**< ::SDL_PRESSED or ::SDL_RELEASED */ | ||||
|     clicks byte       /**< 1 for single-click, 2 for double-click, etc. */ | ||||
|     padding1 byte | ||||
|     x int           /**< X coordinate, relative to window */ | ||||
|     y int           /**< Y coordinate, relative to window */ | ||||
| } | ||||
| 
 | ||||
| pub struct C.SDL_MouseWheelEvent { | ||||
| pub: | ||||
|     @type u32        /**< ::SDL_MOUSEWHEEL */ | ||||
|     timestamp u32   /**< In milliseconds, populated using SDL_GetTicks() */ | ||||
|     windowID u32    /**< The window with mouse focus, if any */ | ||||
|     which u32       /**< The mouse instance id, or SDL_TOUCH_MOUSEID */ | ||||
|     x int           /**< The amount scrolled horizontally, positive to the right and negative to the left */ | ||||
|     y int           /**< The amount scrolled vertically, positive away from the user and negative toward the user */ | ||||
|     direction u32   /**< Set to one of the SDL_MOUSEWHEEL_* defines. When FLIPPED the values in X and Y will be opposite. Multiply by -1 to change them back */ | ||||
| } | ||||
| 
 | ||||
| pub struct C.SDL_JoyAxisEvent { | ||||
| pub: | ||||
|     @type u32        /**< ::SDL_JOYAXISMOTION */ | ||||
|     timestamp u32   /**< In milliseconds, populated using SDL_GetTicks() */ | ||||
|     which int /**< The joystick instance id */ | ||||
|     axis byte         /**< The joystick axis index */ | ||||
|     padding1 byte | ||||
|     padding2 byte | ||||
|     padding3 byte | ||||
|     value i16       /**< The axis value (range: -32768 to 32767) */ | ||||
|     padding4 u16 | ||||
| } | ||||
| 
 | ||||
| pub struct C.SDL_JoyBallEvent { | ||||
| pub: | ||||
|     @type u32        /**< ::SDL_JOYBALLMOTION */ | ||||
|     timestamp u32   /**< In milliseconds, populated using SDL_GetTicks() */ | ||||
|     which int /**< The joystick instance id */ | ||||
|     ball byte         /**< The joystick trackball index */ | ||||
|     padding1 byte | ||||
|     padding2 byte | ||||
|     padding3 byte | ||||
|     xrel i16        /**< The relative motion in the X direction */ | ||||
|     yrel i16        /**< The relative motion in the Y direction */ | ||||
| } | ||||
| 
 | ||||
| pub struct C.SDL_JoyHatEvent { | ||||
| pub: | ||||
| 	@type u32       /**< SDL_JOYHATMOTION */ | ||||
| 	timestamp u32 | ||||
| 	which int       /**< The joystick device index */ | ||||
| 	hat byte        /**< The joystick hat index */ | ||||
| 	value byte      /**< The hat position value: | ||||
| 						*   SDL_HAT_LEFTUP   SDL_HAT_UP       SDL_HAT_RIGHTUP | ||||
| 						*   SDL_HAT_LEFT     SDL_HAT_CENTERED SDL_HAT_RIGHT | ||||
| 						*   SDL_HAT_LEFTDOWN SDL_HAT_DOWN     SDL_HAT_RIGHTDOWN | ||||
| 						*  Note that zero means the POV is centered. | ||||
| 						*/ | ||||
|     padding1 byte | ||||
|     padding2 byte | ||||
| } | ||||
| 
 | ||||
| pub struct C.SDL_JoyButtonEvent { | ||||
| pub: | ||||
| 	@type u32 		/**< SDL_JOYBUTTONDOWN or SDL_JOYBUTTONUP */ | ||||
| 	timestamp u32 | ||||
| 	which int 		/**< The joystick device index */ | ||||
| 	button byte		/**< The joystick button index */ | ||||
| 	state byte		/**< SDL_PRESSED or SDL_RELEASED */ | ||||
|     padding1 byte | ||||
|     padding2 byte | ||||
| } | ||||
| 
 | ||||
| pub struct C.SDL_JoyDeviceEvent { | ||||
| pub: | ||||
|     @type u32        /**< ::SDL_JOYDEVICEADDED or ::SDL_JOYDEVICEREMOVED */ | ||||
|     timestamp u32   /**< In milliseconds, populated using SDL_GetTicks() */ | ||||
|     which int       /**< The joystick device index for the ADDED event, instance id for the REMOVED event */ | ||||
| } | ||||
| 
 | ||||
| pub struct C.SDL_ControllerAxisEvent { | ||||
| pub: | ||||
|     @type u32        /**< ::SDL_CONTROLLERAXISMOTION */ | ||||
|     timestamp u32   /**< In milliseconds, populated using SDL_GetTicks() */ | ||||
|     which int /**< The joystick instance id */ | ||||
|     axis byte         /**< The controller axis (SDL_GameControllerAxis) */ | ||||
|     padding1 byte | ||||
|     padding2 byte | ||||
|     padding3 byte | ||||
|     value i16       /**< The axis value (range: -32768 to 32767) */ | ||||
|     padding4 u16 | ||||
| } | ||||
| 
 | ||||
| pub struct C.SDL_ControllerButtonEvent { | ||||
| pub: | ||||
|     @type u32        /**< ::SDL_CONTROLLERBUTTONDOWN or ::SDL_CONTROLLERBUTTONUP */ | ||||
|     timestamp u32   /**< In milliseconds, populated using SDL_GetTicks() */ | ||||
|     which int /**< The joystick instance id */ | ||||
|     button byte       /**< The controller button (SDL_GameControllerButton) */ | ||||
|     state byte        /**< ::SDL_PRESSED or ::SDL_RELEASED */ | ||||
|     padding1 byte | ||||
|     padding2 byte | ||||
| } | ||||
| 
 | ||||
| pub struct C.SDL_ControllerDeviceEvent { | ||||
| pub: | ||||
|     @type u32        /**< ::SDL_CONTROLLERDEVICEADDED, ::SDL_CONTROLLERDEVICEREMOVED, or ::SDL_CONTROLLERDEVICEREMAPPED */ | ||||
|     timestamp u32   /**< In milliseconds, populated using SDL_GetTicks() */ | ||||
|     which int       /**< The joystick device index for the ADDED event, instance id for the REMOVED or REMAPPED event */ | ||||
| } | ||||
| 
 | ||||
| pub struct C.SDL_AudioDeviceEvent { | ||||
| pub: | ||||
|     @type u32        /**< ::SDL_AUDIODEVICEADDED, or ::SDL_AUDIODEVICEREMOVED */ | ||||
|     timestamp u32   /**< In milliseconds, populated using SDL_GetTicks() */ | ||||
|     which u32       /**< The audio device index for the ADDED event (valid until next SDL_GetNumAudioDevices() call), SDL_AudioDeviceID for the REMOVED event */ | ||||
|     iscapture byte    /**< zero if an output device, non-zero if a capture device. */ | ||||
|     padding1 byte | ||||
|     padding2 byte | ||||
|     padding3 byte | ||||
| } | ||||
| 
 | ||||
| pub struct C.SDL_TouchFingerEvent { | ||||
| pub: | ||||
|     @type u32        /**< ::SDL_FINGERMOTION or ::SDL_FINGERDOWN or ::SDL_FINGERUP */ | ||||
|     timestamp u32   /**< In milliseconds, populated using SDL_GetTicks() */ | ||||
|     touchId i64 /**< The touch device id */ | ||||
|     fingerId i64 | ||||
|     x f32            /**< Normalized in the range 0...1 */ | ||||
|     y f32            /**< Normalized in the range 0...1 */ | ||||
|     dx f32           /**< Normalized in the range -1...1 */ | ||||
|     dy f32           /**< Normalized in the range -1...1 */ | ||||
|     pressure f32     /**< Normalized in the range 0...1 */ | ||||
| } | ||||
| 
 | ||||
| pub struct C.SDL_MultiGestureEvent { | ||||
| pub: | ||||
|     @type u32        /**< ::SDL_MULTIGESTURE */ | ||||
|     timestamp u32   /**< In milliseconds, populated using SDL_GetTicks() */ | ||||
|     touchId i64 /**< The touch device id */ | ||||
|     dTheta f32 | ||||
|     dDist f32 | ||||
|     x f32 | ||||
|     y f32 | ||||
|     numFingers u16 | ||||
|     padding u16 | ||||
| } | ||||
| 
 | ||||
| pub struct C.SDL_DropEvent { | ||||
| pub: | ||||
|     @type u32        /**< ::SDL_DROPBEGIN or ::SDL_DROPFILE or ::SDL_DROPTEXT or ::SDL_DROPCOMPLETE */ | ||||
|     timestamp u32   /**< In milliseconds, populated using SDL_GetTicks() */ | ||||
|     file byteptr         /**< The file name, which should be freed with SDL_free(), is NULL on begin/complete */ | ||||
|     windowID u32    /**< The window that was dropped on, if any */ | ||||
| } | ||||
| 
 | ||||
| pub struct C.SDL_SensorEvent { | ||||
| pub: | ||||
|     @type u32        /**< ::SDL_SENSORUPDATE */ | ||||
|     timestamp u32   /**< In milliseconds, populated using SDL_GetTicks() */ | ||||
|     which int       /**< The instance ID of the sensor */ | ||||
|     data [6]f32      /**< Up to 6 values from the sensor - additional values can be queried using SDL_SensorGetData() */ | ||||
| } | ||||
| 
 | ||||
| pub struct C.SDL_QuitEvent { | ||||
| pub: | ||||
| 	@type u32 /**< SDL_QUIT */ | ||||
| 	timestamp u32 | ||||
| } | ||||
| 
 | ||||
| pub struct C.SDL_UserEvent { | ||||
| pub: | ||||
|     @type u32        /**< ::SDL_USEREVENT through ::SDL_LASTEVENT-1 */ | ||||
|     timestamp u32   /**< In milliseconds, populated using SDL_GetTicks() */ | ||||
|     windowID u32    /**< The associated window if any */ | ||||
|     code int        /**< User defined event code */ | ||||
|     data1 voidptr        /**< User defined data pointer */ | ||||
|     data2 voidptr        /**< User defined data pointer */ | ||||
| } | ||||
|  | @ -1,4 +0,0 @@ | |||
| # SDL2 Image Library | ||||
| Assuming you've installed the dependencies for sdl (already include `SDL2_image` dependency) | ||||
| 
 | ||||
| See the Tvintris example for usage | ||||
|  | @ -1,68 +0,0 @@ | |||
| module image | ||||
| import sdl | ||||
| 
 | ||||
| #flag linux -lSDL2_image | ||||
| 
 | ||||
| #flag windows -I @VROOT/thirdparty/SDL2_image/include | ||||
| #flag windows -L @VROOT/thirdparty/SDL2_image/lib/x64 | ||||
| #flag windows -lSDL2_image | ||||
| 
 | ||||
| #include <SDL_image.h> | ||||
| 
 | ||||
| //////////////////////////////////////////////////////////
 | ||||
| // SDL_Image.h
 | ||||
| //////////////////////////////////////////////////////////
 | ||||
| pub const ( | ||||
| 	IMG_INIT_JPG = 0x00000001 | ||||
|     IMG_INIT_PNG = 0x00000002 | ||||
|     IMG_INIT_TIF = 0x00000004 | ||||
|     IMG_INIT_WEBP = 0x00000008 | ||||
| ) | ||||
| 
 | ||||
| fn C.IMG_Init(flags int) int | ||||
| fn C.IMG_Quit() | ||||
| 
 | ||||
| /* Load an image from an SDL data source. The 'type' may be one of: "BMP", "GIF", "PNG", etc. */ | ||||
| fn C.IMG_LoadTyped_RW(src &SDL_RWops, freesrc int, _type byteptr) &SDL_Surface | ||||
| fn C.IMG_Load(file byteptr) &SDL_Surface | ||||
| fn C.IMG_Load_RW(src &SDL_RWops, freesrc int) &SDL_Surface | ||||
| 
 | ||||
| /* Load an image directly into a render texture. */ | ||||
| fn C.IMG_LoadTexture(renderer &SDL_Renderer, file byteptr) &SDL_Texture | ||||
| fn C.IMG_LoadTexture_RW(renderer &SDL_Renderer, src &SDL_RWops, freesrc int) &SDL_Texture | ||||
| fn C.IMG_LoadTextureTyped_RW(renderer &SDL_Renderer, src &SDL_RWops, freesrc int, _type byteptr) &SDL_Texture | ||||
| 
 | ||||
| /* Functions to detect a file type, given a seekable source */ | ||||
| fn C.IMG_isPNG(src &SDL_RWops) int | ||||
| fn C.IMG_isBMP(src &SDL_RWops) int | ||||
| fn C.IMG_isJPG(src &SDL_RWops) int | ||||
| fn C.IMG_isWEBP(src &SDL_RWops) int | ||||
| 
 | ||||
| /* Individual loading functions */ | ||||
| fn C.IMG_LoadPNG_RW(src &SDL_RWops) &SDL_Surface | ||||
| fn C.IMG_LoadBMP_RW(src &SDL_RWops) &SDL_Surface | ||||
| fn C.IMG_LoadJPG_RW(src &SDL_RWops) &SDL_Surface | ||||
| fn C.IMG_LoadWEBP_RW(src &SDL_RWops) &SDL_Surface | ||||
| 
 | ||||
| /* Individual saving functions */ | ||||
| fn C.IMG_SavePNG(surface voidptr, file byteptr) int | ||||
| fn C.IMG_SavePNG_RW(surface voidptr, dst &SDL_RWops, freedst int) int | ||||
| fn C.IMG_SaveJPG(surface voidptr, file byteptr) int | ||||
| fn C.IMG_SaveJPG_RW(surface voidptr, dst &SDL_RWops, freedst int) int | ||||
| 
 | ||||
| pub fn img_init(flags int) int { | ||||
| 	return C.IMG_Init(flags) | ||||
| } | ||||
| 
 | ||||
| pub fn quit() { | ||||
| 	C.IMG_Quit() | ||||
| } | ||||
| 
 | ||||
| pub fn load(file string) &SDL_Surface { | ||||
| 	res := C.IMG_Load(file.str) | ||||
| 	return res | ||||
| } | ||||
| 
 | ||||
| pub const ( | ||||
|   version = sdl.version // TODO: remove this hack to mark sdl as used; avoids warning
 | ||||
| ) | ||||
|  | @ -1,105 +0,0 @@ | |||
| module mixer | ||||
| import sdl | ||||
| 
 | ||||
| #flag windows -I @VROOT/thirdparty/SDL2_mixer/include | ||||
| #flag windows -L @VROOT/thirdparty/SDL2_mixer/lib/x64 | ||||
| #flag windows -lSDL2_mixer | ||||
| 
 | ||||
| #include <SDL_mixer.h> | ||||
| 
 | ||||
| 
 | ||||
| pub const ( | ||||
| 	MIX_CHANNEL_POST = -2 | ||||
| 	MIX_MAX_VOLUME = C.MIX_MAX_VOLUME | ||||
| 	MIX_CHANNELS = 8 | ||||
| 	MIX_DEFAULT_FREQUENCY = 22050 | ||||
| 	MIX_DEFAULT_FORMAT = C.MIX_DEFAULT_FORMAT | ||||
| 
 | ||||
|     MIX_INIT_FLAC = 0x00000001 | ||||
|     MIX_INIT_MOD = 0x00000002 | ||||
|     MIX_INIT_MP3 = 0x00000008 | ||||
|     MIX_INIT_OGG = 0x00000010 | ||||
|     MIX_INIT_MID = 0x00000020 | ||||
|     MIX_INIT_OPUS = 0x00000040 | ||||
| ) | ||||
| 
 | ||||
| // Structs
 | ||||
| // MIX TODO: get this working as a return type
 | ||||
| pub struct C.Mix_Chunk { | ||||
|     allocated int | ||||
|     abuf &byte // *UInt8
 | ||||
|     alen u32 | ||||
|     volume byte       /* Per-sample volume, 0-128 */ | ||||
| } | ||||
| 
 | ||||
| pub struct C.Mix_Music {} | ||||
| 
 | ||||
| 
 | ||||
| // Methods
 | ||||
| 
 | ||||
| // MIX
 | ||||
| fn C.Mix_Init(flags int) int | ||||
| fn C.Mix_OpenAudio(frequency int, format u16, channels int, chunksize int) int | ||||
| fn C.Mix_CloseAudio() | ||||
| 
 | ||||
| fn C.Mix_LoadMUS(file byteptr) voidptr // *Mix_Music
 | ||||
| fn C.Mix_LoadMUS_RW(src &SDL_RWops, freesrc int) voidptr // *Mix_Music
 | ||||
| fn C.Mix_LoadWAV(file byteptr) voidptr // *Mix_Chunk
 | ||||
| fn C.Mix_LoadWAV_RW(src &SDL_RWops, freesrc int) voidptr // *Mix_Chunk
 | ||||
| 
 | ||||
| // Music
 | ||||
| fn C.Mix_FadeInMusic(music &Mix_Music, loops int, ms int) int | ||||
| fn C.Mix_PlayMusic(music &SDL_AudioSpec, loops int) int | ||||
| fn C.Mix_VolumeMusic(volume int) int | ||||
| fn C.Mix_PauseMusic() | ||||
| fn C.Mix_ResumeMusic() | ||||
| fn C.Mix_RewindMusic() | ||||
| fn C.Mix_SetMusicPosition(position f64) int | ||||
| fn C.Mix_PausedMusic() int | ||||
| fn C.Mix_HaltMusic() int | ||||
| fn C.Mix_FadeOutMusic(ms int) int | ||||
| fn C.Mix_HookMusicFinished(cb fn()) | ||||
| fn C.Mix_FreeMusic(music &Mix_Music) | ||||
| 
 | ||||
| // Channels
 | ||||
| fn C.Mix_VolumeChunk(chunk &Mix_Chunk, volume int) int | ||||
| fn C.Mix_PlayChannel(channel int, chunk &Mix_Chunk, loops int) int | ||||
| fn C.Mix_FadeInChannel(channel int, chunk &Mix_Chunk, loops int, ms int) int | ||||
| fn C.Mix_PlayChannelTimed(channel int, chunk &Mix_Chunk, loops int, ticks int) int | ||||
| fn C.Mix_Pause(channel int) | ||||
| fn C.Mix_Resume(channel int) | ||||
| fn C.Mix_HaltChannel(channel int) int | ||||
| fn C.Mix_ExpireChannel(channel int, ticks int) int | ||||
| fn C.Mix_FadeOutChannel(channel int, ms int) int | ||||
| fn C.Mix_ChannelFinished(cb fn (int)) | ||||
| fn C.Mix_Playing(channel int) int | ||||
| fn C.Mix_Paused(channel int) int | ||||
| fn C.Mix_GetChunk(channel int) voidptr //Mix_Chunk
 | ||||
| fn C.Mix_FreeChunk(chunk &Mix_Chunk) | ||||
| fn C.Mix_ReserveChannels(num int) int | ||||
| 
 | ||||
| // Groups
 | ||||
| fn C.Mix_GroupChannel(which int, tag int) int | ||||
| fn C.Mix_GroupChannels(from int, to int, tag int) int | ||||
| fn C.Mix_GroupAvailable(tag int) int | ||||
| fn C.Mix_GroupCount(tag int) int | ||||
| fn C.Mix_GroupOldest(tag int) int | ||||
| fn C.Mix_GroupNewer(tag int) int | ||||
| fn C.Mix_FadeOutGroup(tag int, ms int) int | ||||
| fn C.Mix_HaltGroup(tag int) int | ||||
| 
 | ||||
| // Effects
 | ||||
| type EffectFunc fn (int, voidptr, int, voidptr) // int chan, void *stream, int len, void *udata
 | ||||
| type EffectDone fn (int, voidptr) // int chan, void *udata
 | ||||
| 
 | ||||
| fn C.Mix_RegisterEffect(channel int, f EffectFunc, d EffectDone, arg voidptr) int | ||||
| fn C.Mix_UnregisterEffect(channel int, f EffectFunc) int | ||||
| fn C.Mix_UnregisterAllEffects(channel int) int | ||||
| fn C.Mix_SetPanning(channel int, left byte, right byte) int | ||||
| fn C.Mix_SetDistance(channel int, distance byte) int | ||||
| fn C.Mix_SetPosition(channel int, angle i16, distance byte) int | ||||
| fn C.Mix_SetReverseStereo(channel int, flip int) int | ||||
| 
 | ||||
| pub const ( | ||||
|   version = sdl.version // TODO: remove this hack to mark sdl as used; avoids warning
 | ||||
| ) | ||||
							
								
								
									
										220
									
								
								vlib/sdl/sdl.v
								
								
								
								
							
							
						
						
									
										220
									
								
								vlib/sdl/sdl.v
								
								
								
								
							|  | @ -1,220 +0,0 @@ | |||
| // Copyright(C) 2019 Nicolas Sauzede. All rights reserved.
 | ||||
| // Use of this source code is governed by an MIT license
 | ||||
| // that can be found in the LICENSE file.
 | ||||
| 
 | ||||
| module sdl | ||||
| 
 | ||||
| #flag linux `sdl2-config --cflags --libs`  -lSDL2_ttf -lSDL2_mixer -lSDL2_image | ||||
| #flag darwin `sdl2-config --cflags --libs`  -lSDL2_ttf -lSDL2_mixer -lSDL2_image | ||||
| #flag solaris `sdl2-config --cflags --libs`  -lSDL2_ttf -lSDL2_mixer -lSDL2_image | ||||
| 
 | ||||
| //#flag windows `sdl2-config --cflags`
 | ||||
| //#flag windows `sdl2-config --libs`  -lSDL2_ttf -lSDL2_mixer -lSDL2_image
 | ||||
| //#flag `sdl2-config --cflags --libs`  -lSDL2_ttf -lSDL2_mixer -lSDL2_image
 | ||||
| 
 | ||||
| #flag -DSDL_DISABLE_IMMINTRIN_H | ||||
| 
 | ||||
| #flag windows -I @VROOT/thirdparty/SDL2/include | ||||
| #flag windows -Dmain=SDL_main | ||||
| #flag windows -lSDL2main -lSDL2 | ||||
| #flag windows -L @VROOT/thirdparty/SDL2/lib/x64 | ||||
| 
 | ||||
| #include <SDL.h> | ||||
| 
 | ||||
| 
 | ||||
| pub struct C.SDL_RWops {} | ||||
| pub struct C.SDL_Window {} | ||||
| pub struct C.SDL_Renderer {} | ||||
| pub struct C.SDL_Texture {} | ||||
| 
 | ||||
| pub struct C.SDL_Color{ | ||||
| pub: | ||||
|         r byte | ||||
|         g byte | ||||
|         b byte | ||||
|         a byte | ||||
| } | ||||
| 
 | ||||
| pub struct C.SDL_Rect { | ||||
| pub mut: | ||||
| 	x int | ||||
| 	y int | ||||
| 	w int | ||||
| 	h int | ||||
| } | ||||
| 
 | ||||
| pub struct C.SDL_Surface { | ||||
| pub: | ||||
| 	flags u32 | ||||
| 	format voidptr | ||||
| 	w int | ||||
| 	h int | ||||
| 	pitch int | ||||
| 	pixels voidptr | ||||
| 	userdata voidptr | ||||
| 	locked int | ||||
| 	lock_data voidptr | ||||
| 	clip_rect SDL_Rect | ||||
| 	map voidptr | ||||
| 	refcount int | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| struct Keysym { | ||||
| pub: | ||||
|         scancode int                       /**< hardware specific scancode */ | ||||
|         sym int                            /**< SDL virtual keysym */ | ||||
|         mod u16                            /**< current key modifiers */ | ||||
|         unused u32                         /**< translated character */ | ||||
| } | ||||
| 
 | ||||
| pub struct C.SDL_AudioSpec { | ||||
| pub mut: | ||||
|         freq int                           /**< DSP frequency -- samples per second */ | ||||
|         format u16                         /**< Audio data format */ | ||||
|         channels byte                      /**< Number of channels: 1 mono, 2 stereo */ | ||||
|         silence byte                       /**< Audio buffer silence value (calculated) */ | ||||
|         samples u16                        /**< Audio buffer size in samples (power of 2) */ | ||||
|         size u32                           /**< Necessary for some compile environments */ | ||||
|         callback voidptr | ||||
|         userdata voidptr | ||||
| } | ||||
| 
 | ||||
| // pub struct RwOps {
 | ||||
| // pub:
 | ||||
| // mut:
 | ||||
| //         seek voidptr
 | ||||
| //         read voidptr
 | ||||
| //         write voidptr
 | ||||
| //         close voidptr
 | ||||
| //         type_ u32
 | ||||
| //         hidden voidptr
 | ||||
| // }
 | ||||
| //type AudioSpec C.voidptrioSpec
 | ||||
| 
 | ||||
| fn C.atexit(func fn ()) | ||||
| 
 | ||||
| ///////////////////////////////////////////////////
 | ||||
| fn C.SDL_MapRGB(fmt voidptr byte, g byte, b byte) u32 | ||||
| fn C.SDL_CreateRGBSurface(flags u32, width int, height int, depth int, Rmask u32, Gmask u32, Bmask u32, Amask u32) voidptr | ||||
| fn C.SDL_PollEvent(&SDL_Event) int | ||||
| fn C.SDL_NumJoysticks() int | ||||
| fn C.SDL_JoystickNameForIndex(device_index int) voidptr | ||||
| fn C.SDL_RenderCopy(renderer voidptr, texture voidptr, srcrect voidptr, dstrect voidptr) int | ||||
| fn C.SDL_CreateWindow(title byteptr, x int, y int, w int, h int, flags u32) voidptr | ||||
| fn C.SDL_CreateRenderer(window &SDL_Window, index int, flags u32) voidptr | ||||
| fn C.SDL_CreateWindowAndRenderer(width int, height int, window_flags u32, window &voidptr, renderer &voidptr) int | ||||
| fn C.SDL_DestroyWindow(window voidptr) | ||||
| fn C.SDL_DestroyRenderer(renderer voidptr) | ||||
| fn C.SDL_GetWindowSize(window voidptr, w voidptr, h voidptr) | ||||
| fn C.SDL_SetHint(name byteptr, value byteptr) C.SDL_bool | ||||
| //fn C.SDL_RWFromFile(byteptr, byteptr) &RwOps
 | ||||
| //fn C.SDL_CreateTextureFromSurface(renderer &C.SDL_Renderer, surface &C.SDL_Surface) &C.SDL_Texture
 | ||||
| fn C.SDL_CreateTextureFromSurface(renderer voidptr, surface voidptr) voidptr | ||||
| fn C.SDL_CreateTexture(renderer voidptr, format u32, access int, w int, h int) voidptr | ||||
| fn C.SDL_FillRect(dst voidptr, dstrect voidptr, color u32) int | ||||
| fn C.SDL_SetRenderDrawColor(renderer voidptr, r byte, g byte, b byte, a byte) | ||||
| fn C.SDL_RenderPresent(renderer voidptr) | ||||
| fn C.SDL_RenderClear(renderer voidptr) int | ||||
| fn C.SDL_UpdateTexture(texture voidptr, rect voidptr, pixels voidptr, pitch int) int | ||||
| fn C.SDL_QueryTexture(texture voidptr, format voidptr, access voidptr, w voidptr, h voidptr) int | ||||
| fn C.SDL_DestroyTexture(texture voidptr) | ||||
| fn C.SDL_FreeSurface(surface voidptr) | ||||
| fn C.SDL_Init(flags u32) int | ||||
| fn C.SDL_Quit() | ||||
| fn C.SDL_SetWindowTitle(window voidptr, title byteptr) | ||||
| // following is wrong : SDL_Zero is a macro accepting an argument
 | ||||
| fn C.SDL_zero() | ||||
| fn C.SDL_LoadWAV(file byteptr, spec voidptr, audio_buf voidptr, audio_len voidptr) voidptr | ||||
| fn C.SDL_FreeWAV(audio_buf voidptr) | ||||
| fn C.SDL_OpenAudio(desired voidptr, obtained voidptr) int | ||||
| fn C.SDL_CloseAudio() | ||||
| fn C.SDL_PauseAudio(pause_on int) | ||||
| fn C.SDL_JoystickOpen(device_index int) int | ||||
| fn C.SDL_JoystickEventState(state int) int | ||||
| 
 | ||||
| //////////////////////////////////////////////////////////
 | ||||
| // SDL_Timer.h
 | ||||
| //////////////////////////////////////////////////////////
 | ||||
| fn C.SDL_GetTicks() u32 | ||||
| fn C.SDL_TICKS_PASSED(a,b u32) bool | ||||
| fn C.SDL_GetPerformanceCounter() u64 | ||||
| fn C.SDL_GetPerformanceFrequency() u64 | ||||
| fn C.SDL_Delay(ms u32) | ||||
| 
 | ||||
| //////////////////////////////////////////////////////////
 | ||||
| // GL
 | ||||
| //////////////////////////////////////////////////////////
 | ||||
| fn C.SDL_GL_SetAttribute(attr int, value int) int | ||||
| fn C.SDL_GL_CreateContext(window voidptr) voidptr | ||||
| fn C.SDL_GL_MakeCurrent(window voidptr, context voidptr) int | ||||
| fn C.SDL_GL_SetSwapInterval(interval int) int | ||||
| fn C.SDL_GL_SwapWindow(window voidptr) | ||||
| fn C.SDL_GL_DeleteContext(context voidptr) | ||||
| 
 | ||||
| pub fn create_texture_from_surface(renderer voidptr, surface &SDL_Surface) voidptr { | ||||
| 	return C.SDL_CreateTextureFromSurface(renderer, voidptr(surface)) | ||||
| } | ||||
| 
 | ||||
| pub fn create_window_and_renderer(width int, height int, window_flags u32, window voidptr, renderer voidptr) int { | ||||
| 	return C.SDL_CreateWindowAndRenderer(width, height, window_flags, window, renderer) | ||||
| } | ||||
| 
 | ||||
| pub fn joystick_name_for_index(device_index int) byteptr { | ||||
| 	return byteptr(C.SDL_JoystickNameForIndex(device_index)) | ||||
| } | ||||
| 
 | ||||
| pub fn fill_rect(screen &SDL_Surface, rect &SDL_Rect, _col &SDL_Color) { | ||||
| 	col := C.SDL_MapRGB(screen.format, _col.r, _col.g, _col.b) | ||||
| 	_screen := voidptr(screen) | ||||
| 	_rect := voidptr(rect) | ||||
| 	C.SDL_FillRect(_screen, _rect, col) | ||||
| } | ||||
| 
 | ||||
| pub fn create_rgb_surface(flags u32, width int, height int, depth int, rmask u32, gmask u32, bmask u32, amask u32) &SDL_Surface { | ||||
| 	res := C.SDL_CreateRGBSurface(flags, width, height, depth, rmask, gmask, bmask, amask) | ||||
| 	return res | ||||
| } | ||||
| 
 | ||||
| pub fn render_copy(renderer voidptr, texture voidptr, srcrect &SDL_Rect, dstrect &SDL_Rect) int { | ||||
| 	_srcrect := voidptr(srcrect) | ||||
| 	_dstrect := voidptr(dstrect) | ||||
| 	return C.SDL_RenderCopy(renderer, texture, _srcrect, _dstrect) | ||||
| } | ||||
| 
 | ||||
| pub fn poll_event(event &C.SDL_Event) int { | ||||
| 	return C.SDL_PollEvent(event) | ||||
| } | ||||
| 
 | ||||
| pub fn destroy_texture(text voidptr) { | ||||
|         C.SDL_DestroyTexture(text) | ||||
| } | ||||
| 
 | ||||
| pub fn free_surface(surf &SDL_Surface) { | ||||
| 	_surf := voidptr(surf) | ||||
|         C.SDL_FreeSurface(_surf) | ||||
| } | ||||
| 
 | ||||
| pub fn get_ticks() u32 { | ||||
|         return C.SDL_GetTicks() | ||||
| } | ||||
| 
 | ||||
| pub fn ticks_passed(a, b u32) bool { | ||||
|         return C.SDL_TICKS_PASSED(a,b) | ||||
| } | ||||
| 
 | ||||
| pub fn get_perf_counter() u64 { | ||||
|         return C.SDL_GetPerformanceCounter() | ||||
| } | ||||
| 
 | ||||
| pub fn get_perf_frequency() u64 { | ||||
|         return C.SDL_GetPerformanceFrequency() | ||||
| } | ||||
| 
 | ||||
| pub fn delay(ms u32) { | ||||
|         C.SDL_Delay(ms) | ||||
| } | ||||
| 
 | ||||
| pub const ( | ||||
|   version = '0.2' // hack to avoid unused module warning in the main program
 | ||||
| ) | ||||
|  | @ -1,142 +0,0 @@ | |||
| module ttf | ||||
| 
 | ||||
| import sdl | ||||
| 
 | ||||
| #flag windows -I @VROOT/thirdparty/SDL2_ttf/include | ||||
| #flag windows -L @VROOT/thirdparty/SDL2_ttf/lib/x64 | ||||
| #flag windows -lSDL2_ttf | ||||
| 
 | ||||
| #include <SDL_ttf.h> | ||||
| 
 | ||||
| [typedef] | ||||
| struct C.TTF_Font {} | ||||
| 
 | ||||
| fn C.TTF_Init() int | ||||
| fn C.TTF_Quit() | ||||
| 
 | ||||
| fn C.TTF_OpenFont(file byteptr, ptsize int) &TTF_Font | ||||
| fn C.TTF_OpenFontIndex(file byteptr, ptsize int, index i64) &TTF_Font | ||||
| fn C.TTF_OpenFontRW(src &SDL_RWops, freesrc int, ptsize int) &TTF_Font | ||||
| fn C.TTF_OpenFontIndexRW(src &SDL_RWops, freesrc int, ptsize int, index i64) &TTF_Font | ||||
| 
 | ||||
| /* Set and retrieve the font style */ | ||||
| const ( | ||||
| 	TTF_STYLE_NORMAL = C.TTF_STYLE_NORMAL | ||||
| 	TTF_STYLE_BOLD = C.TTF_STYLE_BOLD | ||||
| 	TTF_STYLE_ITALIC = C.TTF_STYLE_ITALIC | ||||
| 	TTF_STYLE_UNDERLINE = C.TTF_STYLE_UNDERLINE | ||||
| 	TTF_STYLE_STRIKETHROUGH = C.TTF_STYLE_STRIKETHROUGH | ||||
| ) | ||||
| fn C.TTF_GetFontStyle(font &TTF_Font) int | ||||
| fn C.TTF_SetFontStyle(font &TTF_Font, style int) | ||||
| fn C.TTF_GetFontOutline(font &TTF_Font) int | ||||
| fn C.TTF_SetFontOutline(font &TTF_Font, outline int) | ||||
| 
 | ||||
| /* Set and retrieve FreeType hinter settings */ | ||||
| const ( | ||||
| 	TTF_HINTING_NORMAL = C.TTF_HINTING_NORMAL | ||||
| 	TTF_HINTING_LIGHT = C.TTF_HINTING_LIGHT | ||||
| 	TTF_HINTING_MONO = C.TTF_HINTING_MONO | ||||
| 	TTF_HINTING_NONE = C.TTF_HINTING_NONE | ||||
| ) | ||||
| fn C.TTF_GetFontHinting(font &TTF_Font) int | ||||
| fn C.TTF_SetFontHinting(font &TTF_Font, hinting int) | ||||
| 
 | ||||
| /* Get the total height of the font - usually equal to point size */ | ||||
| fn C.TTF_FontHeight(font &TTF_Font) int | ||||
| 
 | ||||
| /* Get the offset from the baseline to the top of the font This is a positive value, relative to the baseline. | ||||
|  */ | ||||
| fn C.TTF_FontAscent(font &TTF_Font) int | ||||
| 
 | ||||
| /* Get the offset from the baseline to the bottom of the font This is a negative value, relative to the baseline. */ | ||||
| fn C.TTF_FontDescent(font &TTF_Font) int | ||||
| 
 | ||||
| /* Get the recommended spacing between lines of text for this font */ | ||||
| fn C.TTF_FontLineSkip(font &TTF_Font) int | ||||
| 
 | ||||
| /* Get/Set whether or not kerning is allowed for this font */ | ||||
| fn C.TTF_GetFontKerning(font &TTF_Font) int | ||||
| fn C.TTF_SetFontKerning(font &TTF_Font, allowed int) | ||||
| 
 | ||||
| /* Get the kerning size of two glyphs */ | ||||
| fn C.TTF_GetFontKerningSizeGlyphs(font &TTF_Font, previous_ch u16, ch u16) int | ||||
| 
 | ||||
| /* Get the number of faces of the font */ | ||||
| fn C.TTF_FontFaces(font &TTF_Font) i64 | ||||
| 
 | ||||
| /* Get the font face attributes, if any */ | ||||
| fn C.TTF_FontFaceIsFixedWidth(font &TTF_Font) int | ||||
| fn C.TTF_FontFaceFamilyName(font &TTF_Font) byteptr | ||||
| fn C.TTF_FontFaceStyleName(font &TTF_Font) byteptr | ||||
| 
 | ||||
| /* Check wether a glyph is provided by the font or not */ | ||||
| fn C.TTF_GlyphIsProvided(font &TTF_Font, ch u16) int | ||||
| 
 | ||||
| /* Get the metrics (dimensions) of a glyph To understand what these metrics mean, here is a useful link: | ||||
|     http://freetype.sourceforge.net/freetype2/docs/tutorial/step2.html
 | ||||
|  */ | ||||
| fn C.TTF_GlyphMetrics(font &TTF_Font, ch u16, minx &int, maxx &int, miny &int, maxy &int, advance &int) int | ||||
| 
 | ||||
| /* Get the dimensions of a rendered string of text */ | ||||
| fn C.TTF_SizeText(font &TTF_Font, text byteptr, w &int, h &int) int | ||||
| fn C.TTF_SizeUTF8(font &TTF_Font, text byteptr, w &int, h &int) int | ||||
| fn C.TTF_SizeUNICODE(font &TTF_Font, text &u16, w &int, h &int) int | ||||
| 
 | ||||
| /* Create an 8-bit palettized surface and render the given text at fast quality with the given font and color.  The 0 pixel is the | ||||
|    colorkey, giving a transparent background, and the 1 pixel is set to the text color. | ||||
|    This function returns the new surface, or NULL if there was an error. | ||||
| */ | ||||
| fn C.TTF_RenderText_Solid(font &TTF_Font, text byteptr, fg SDL_Color) &SDL_Surface | ||||
| fn C.TTF_RenderUTF8_Solid(font &TTF_Font, text byteptr, fg SDL_Color) &SDL_Surface | ||||
| fn C.TTF_RenderUNICODE_Solid(font &TTF_Font, text &u16, fg SDL_Color) &SDL_Surface | ||||
| 
 | ||||
| /* Create an 8-bit palettized surface and render the given glyph at fast quality with the given font and color.  The 0 pixel is the | ||||
|    colorkey, giving a transparent background, and the 1 pixel is set to the text color.  The glyph is rendered without any padding or | ||||
|    centering in the X direction, and aligned normally in the Y direction. This function returns the new surface, or NULL if there was an error. | ||||
| */ | ||||
| fn C.TTF_RenderGlyph_Solid(font &TTF_Font, ch u16, fg C.SDL_Color) &SDL_Surface | ||||
| 
 | ||||
| /* Create an 8-bit palettized surface and render the given text at high quality with the given font and colors.  The 0 pixel is background, | ||||
|    while other pixels have varying degrees of the foreground color. This function returns the new surface, or NULL if there was an error. | ||||
| */ | ||||
| fn C.TTF_RenderText_Shaded(font &TTF_Font, text byteptr, fg SDL_Color, bg SDL_Color) &SDL_Surface | ||||
| fn C.TTF_RenderUTF8_Shaded(font &TTF_Font, text byteptr, fg SDL_Color, bg SDL_Color) &SDL_Surface | ||||
| fn C.TTF_RenderUNICODE_Shaded(font &TTF_Font, text &u16, fg SDL_Color, bg SDL_Color) &SDL_Surface | ||||
| 
 | ||||
| /* Create an 8-bit palettized surface and render the given glyph at high quality with the given font and colors.  The 0 pixel is background, | ||||
|    while other pixels have varying degrees of the foreground color. The glyph is rendered without any padding or centering in the X | ||||
|    direction, and aligned normally in the Y direction. This function returns the new surface, or NULL if there was an error. | ||||
| */ | ||||
| fn C.TTF_RenderGlyph_Shaded(font &TTF_Font, ch u16, fg C.SDL_Color) &SDL_Surface | ||||
| 
 | ||||
| /* Create a 32-bit ARGB surface and render the given text at high quality, using alpha blending to dither the font with the given color. | ||||
|    This function returns the new surface, or NULL if there was an error. | ||||
| */ | ||||
| fn C.TTF_RenderText_Blended(font &TTF_Font, text byteptr, fg SDL_Color, bg SDL_Color) &SDL_Surface | ||||
| fn C.TTF_RenderUTF8_Blended(font &TTF_Font, text byteptr, fg SDL_Color, bg SDL_Color) &SDL_Surface | ||||
| fn C.TTF_RenderUNICODE_Blended(font &TTF_Font, text &u16, fg SDL_Color, bg SDL_Color) &SDL_Surface | ||||
| 
 | ||||
| 
 | ||||
| /* Create a 32-bit ARGB surface and render the given text at high quality, using alpha blending to dither the font with the given color. | ||||
|    Text is wrapped to multiple lines on line endings and on word boundaries if it extends beyond wrapLength in pixels. | ||||
|    This function returns the new surface, or NULL if there was an error. | ||||
| */ | ||||
| fn C.TTF_RenderText_Blended_Wrapped(font &TTF_Font, text byteptr, fg SDL_Color, wrap_length u32) &SDL_Surface | ||||
| fn C.TTF_RenderUTF8_Blended_Wrapped(font &TTF_Font, text byteptr, fg SDL_Color, wrap_length u32) &SDL_Surface | ||||
| fn C.TTF_RenderUNICODE_Blended_Wrapped(font &TTF_Font, text &u16, fg SDL_Color, wrap_length u32) &SDL_Surface | ||||
| 
 | ||||
| /* Create a 32-bit ARGB surface and render the given glyph at high quality, using alpha blending to dither the font with the given color. | ||||
|    The glyph is rendered without any padding or centering in the X direction, and aligned normally in the Y direction. | ||||
|    This function returns the new surface, or NULL if there was an error. | ||||
| */ | ||||
| fn C.TTF_RenderGlyph_Blended(font &TTF_Font, ch u16, fg C.SDL_Color) &SDL_Surface | ||||
| 
 | ||||
| fn C.TTF_WasInit() int | ||||
| 
 | ||||
| fn C.TTF_CloseFont(font &TTF_Font) | ||||
| 
 | ||||
| pub const ( | ||||
|   version = '0.0.1' | ||||
|   sdl_version = sdl.version // TODO: remove this hack to mark sdl as used; avoids warning
 | ||||
| ) | ||||
|  | @ -1,4 +1,5 @@ | |||
| 
 | ||||
| fn todo() {} | ||||
| /* | ||||
| // QTODO
 | ||||
| fn simple<T>(p T) T { | ||||
|  |  | |||
|  | @ -4,6 +4,8 @@ interface Speaker { | |||
| 	say() string | ||||
| } | ||||
| 
 | ||||
| fn todo() {} | ||||
| 
 | ||||
| /* | ||||
| // QTODO
 | ||||
| struct ChatRoom { | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue