Compare commits
4 Commits
Author | SHA1 | Date |
---|---|---|
Barra Ó Catháin | 926f5f5da2 | |
Barra Ó Catháin | a50469e1f7 | |
Barra Ó Catháin | fa3d3ca843 | |
Barra Ó Catháin | 42de9f0616 |
Binary file not shown.
|
@ -1,4 +0,0 @@
|
||||||
(defun hello-world ()
|
|
||||||
(format t "Hello, world!"))
|
|
||||||
|
|
||||||
(hello-world)
|
|
|
@ -1,2 +0,0 @@
|
||||||
|
|
||||||
((:TITLE "Jailbreak" :ARTIST "Thin Lizzy" :RATING 10 :RIPPED T) (:TITLE "Lateralus" :ARTIST "TOOL" :RATING 10 :RIPPED T) (:TITLE "Poopenfarten" :ARTIST "Zweibrüder" :RATING 11 :RIPPED T) (:TITLE "Ride The Lightning" :ARTIST "Metallica" :RATING 9 :RIPPED T) (:TITLE "The Sound Of Rancid Juices Sloshing Around Your Coffin" :ARTIST "Last Days Of Humanity" :RATING 5 :RIPPED T))
|
|
Binary file not shown.
|
@ -1,94 +0,0 @@
|
||||||
;;;; Simple CD Database program:
|
|
||||||
(defvar *cd-database* nil "The current state of the CD database.")
|
|
||||||
|
|
||||||
(defun make-cd (title artist rating ripped)
|
|
||||||
"Creates a CD record."
|
|
||||||
(list :title title :artist artist :rating rating :ripped ripped))
|
|
||||||
|
|
||||||
(defun add-cd (cd)
|
|
||||||
"Adds a CD record to the database."
|
|
||||||
(push cd *cd-database*) (setf *cd-database* (sort *cd-database* #'cd-sort-by-title)))
|
|
||||||
|
|
||||||
(defun print-cd-database (&optional database)
|
|
||||||
"Prints the current CD database, or, optionally, a passed in database."
|
|
||||||
(if database
|
|
||||||
(dolist (cd database)
|
|
||||||
(format t "~{~a: ~10t~a~%~}~%" cd))
|
|
||||||
(dolist (cd *cd-database*)
|
|
||||||
(format t "~{~a: ~10t~a~%~}~%" cd))))
|
|
||||||
|
|
||||||
(defun prompt-read (prompt)
|
|
||||||
"Prompts for a single line of user input."
|
|
||||||
(format *query-io* "~a: " prompt)
|
|
||||||
(force-output *query-io*)
|
|
||||||
(read-line *query-io*))
|
|
||||||
|
|
||||||
(defun prompt-for-cd ()
|
|
||||||
"Creates a CD record using user input."
|
|
||||||
(make-cd
|
|
||||||
(prompt-read "Title")
|
|
||||||
(prompt-read "Artist")
|
|
||||||
(or (parse-integer (prompt-read "Rating") :junk-allowed t) 0)
|
|
||||||
(y-or-n-p "Ripped [y/n]: ")))
|
|
||||||
|
|
||||||
(defun add-cds ()
|
|
||||||
"Adds one or more CDs to the database with user input."
|
|
||||||
(loop (add-cd (prompt-for-cd))
|
|
||||||
(if (not (y-or-n-p "Another? [y/n]: ")) (return))))
|
|
||||||
|
|
||||||
(defun cd-sort-by-title (a b)
|
|
||||||
"Sorts two CD records alphabetically."
|
|
||||||
(string< (getf a :title) (getf b :title)))
|
|
||||||
|
|
||||||
(defun save-cds (filename)
|
|
||||||
"Saves the CD database to a file."
|
|
||||||
(with-open-file
|
|
||||||
(file-output filename
|
|
||||||
:direction :output
|
|
||||||
:if-exists :supersede)
|
|
||||||
(with-standard-io-syntax
|
|
||||||
(print *cd-database* file-output))))
|
|
||||||
|
|
||||||
(defun read-cds (filename)
|
|
||||||
"Loads a CD database from a file."
|
|
||||||
(with-open-file
|
|
||||||
(file-input filename)
|
|
||||||
(with-standard-io-syntax
|
|
||||||
(print-cd-database (setf *cd-database* (read file-input))))))
|
|
||||||
|
|
||||||
(defun delete-cds (selector-function)
|
|
||||||
"Deletes CD records according to a selector function."
|
|
||||||
(print-cd-database (setq *cd-database* (remove-if selector-function *cd-database*))))
|
|
||||||
|
|
||||||
(defun select (selector-function)
|
|
||||||
"Select records from a database based on a selector function."
|
|
||||||
(print-cd-database (remove-if-not selector-function *cd-database*)))
|
|
||||||
|
|
||||||
(defun update (selector-function &key title artist rating (ripped nil ripped-p))
|
|
||||||
"Update selected records in a database."
|
|
||||||
(setf *cd-database*
|
|
||||||
(mapcar
|
|
||||||
#'(lambda (row)
|
|
||||||
(when (funcall selector-function row)
|
|
||||||
(if title (setf (getf row :title) title))
|
|
||||||
(if artist (setf (getf row :artist) artist))
|
|
||||||
(if rating (setf (getf row :rating) rating))
|
|
||||||
(if ripped-p (setf (getf row :ripped) ripped)))
|
|
||||||
row) *cd-database*)))
|
|
||||||
|
|
||||||
(defun make-comparison-expression (field value)
|
|
||||||
"Create a comparison function for a field and a value in a plist."
|
|
||||||
`(equal (getf cd ,field) ,value))
|
|
||||||
|
|
||||||
(defun make-comparisons-list (fields)
|
|
||||||
"Create a list of plist comparison functions."
|
|
||||||
(loop while fields
|
|
||||||
collecting (make-comparison-expression (pop fields) (pop fields))))
|
|
||||||
|
|
||||||
(defmacro where (&rest clauses)
|
|
||||||
"Create an expression where all plist comparisons must be true."
|
|
||||||
`#'(lambda (row) (and ,@(make-comparisons-list clauses))))
|
|
||||||
|
|
||||||
;; Load up the CD database on startup:
|
|
||||||
(read-cds "~/.cds.db")
|
|
||||||
(print-cd-database)
|
|
Binary file not shown.
|
@ -1,38 +0,0 @@
|
||||||
(defpackage :BARRA-TESTING-FRAMEWORK
|
|
||||||
(:use :common-lisp))
|
|
||||||
|
|
||||||
(in-package "BARRA-TESTING-FRAMEWORK")
|
|
||||||
|
|
||||||
(defvar *test-name* nil)
|
|
||||||
|
|
||||||
(defmacro with-gensyms ((&rest names) &body body)
|
|
||||||
`(let ,(loop for n in names collect `(,n (gensym)))
|
|
||||||
,@body))
|
|
||||||
|
|
||||||
(defmacro deftest (name parameters &body body)
|
|
||||||
"Define a test function. Within a test function we can call
|
|
||||||
other test functions or use 'check' to run individual test
|
|
||||||
cases."
|
|
||||||
`(defun ,name ,parameters
|
|
||||||
(let ((*test-name* (append *test-name* (list ',name))))
|
|
||||||
,@body)))
|
|
||||||
|
|
||||||
(defmacro check (&body forms)
|
|
||||||
"Run each expression in 'forms' as a test case."
|
|
||||||
`(combine-results
|
|
||||||
,@(loop for f in forms collect `(report-result ,f ',f))))
|
|
||||||
|
|
||||||
(defmacro combine-results (&body forms)
|
|
||||||
"Combine the results (as booleans) of evaluating 'forms' in order."
|
|
||||||
(with-gensyms (result)
|
|
||||||
`(let ((,result t))
|
|
||||||
,@(loop for f in forms collect `(unless ,f (setf ,result nil)))
|
|
||||||
,result)))
|
|
||||||
|
|
||||||
(defun report-result (result form)
|
|
||||||
"Report the results of a single test case. Called by 'check'."
|
|
||||||
(format t "~:[FAIL~;PASS~] - ~a: ~a~%" result *test-name* form)
|
|
||||||
result)
|
|
||||||
|
|
||||||
(let ((pack (find-package :foo)))
|
|
||||||
(do-all-symbols (sym pack) (when (eql (symbol-package sym) pack) (export sym))))
|
|
Binary file not shown.
|
@ -1,99 +0,0 @@
|
||||||
(defpackage BARRA-FILENAME-PACKAGE
|
|
||||||
(:use common-lisp)
|
|
||||||
(:export
|
|
||||||
:component-present-p
|
|
||||||
:directory-pathname-p
|
|
||||||
:pathname-as-directory
|
|
||||||
:pathname-as-file
|
|
||||||
:directory-wildcard
|
|
||||||
:file-exists-p
|
|
||||||
:list-directory
|
|
||||||
:walk-directory))
|
|
||||||
|
|
||||||
(in-package BARRA-FILENAME-PACKAGE)
|
|
||||||
|
|
||||||
(defun component-present-p (value)
|
|
||||||
(and value (not (eql value :unspecified))))
|
|
||||||
|
|
||||||
(defun directory-pathname-p (pathname)
|
|
||||||
(and
|
|
||||||
(not (component-present-p (pathname-name pathname)))
|
|
||||||
(not (component-present-p (pathname-type pathname)))))
|
|
||||||
|
|
||||||
(defun pathname-as-directory (path)
|
|
||||||
(let ((pathname (pathname path)))
|
|
||||||
(if
|
|
||||||
(directory-pathname-p pathname)
|
|
||||||
pathname
|
|
||||||
(make-pathname
|
|
||||||
:host (pathname-host pathname)
|
|
||||||
:device (pathname-device pathname)
|
|
||||||
:directory (append (or (pathname-directory pathname) (file-namestring pathname))
|
|
||||||
(list (file-namestring pathname)))
|
|
||||||
:name nil
|
|
||||||
:type nil
|
|
||||||
:defaults pathname))))
|
|
||||||
|
|
||||||
(defun directory-wildcard (dirname)
|
|
||||||
(make-pathname
|
|
||||||
:name :wild
|
|
||||||
:type #-clisp :wild #+clisp nil
|
|
||||||
:defaults (pathname-as-directory dirname)))
|
|
||||||
|
|
||||||
(defun list-directory (dirname)
|
|
||||||
(when (wild-pathname-p dirname)
|
|
||||||
(error "Can only list concrete directory names."))
|
|
||||||
(directory (directory-wildcard dirname)))
|
|
||||||
|
|
||||||
(defun file-exists-p (pathname)
|
|
||||||
#+(or sbcl lispworks openmcl)
|
|
||||||
(probe-file pathname)
|
|
||||||
|
|
||||||
#+(or allegro cmu)
|
|
||||||
(or (probe-file (pathname-as-directory pathname))
|
|
||||||
(probe-file pathname))
|
|
||||||
|
|
||||||
#+clisp
|
|
||||||
(or (ignore-errors
|
|
||||||
(probe-file (pathname-as-file pathname)))
|
|
||||||
(ignore-errors
|
|
||||||
(let ((directory-form (pathname-as-directory pathname)))
|
|
||||||
(when (ext:probe-directory directory-form)
|
|
||||||
directory-form))))
|
|
||||||
|
|
||||||
#-(or sbcl cmu lispworks openmcl allegro clisp)
|
|
||||||
(error "list-directory not implemented"))
|
|
||||||
|
|
||||||
#+clisp
|
|
||||||
(defun clisp-subdirectories-wildcard (wildcard)
|
|
||||||
(make-pathname
|
|
||||||
:directory (append (pathname-directory wildcard) (list :wild))
|
|
||||||
:name nil
|
|
||||||
:type nil
|
|
||||||
:defaults wildcard))
|
|
||||||
|
|
||||||
(defun pathname-as-file (name)
|
|
||||||
(let ((pathname (pathname name)))
|
|
||||||
(when (wild-pathname-p pathname)
|
|
||||||
(error "Can't reliably convert wild pathnames."))
|
|
||||||
(if (directory-pathname-p name)
|
|
||||||
(let* ((directory (pathname-directory pathname))
|
|
||||||
(name-and-type (pathname (first (last directory)))))
|
|
||||||
(make-pathname
|
|
||||||
:directory (butlast directory)
|
|
||||||
:name (pathname-name name-and-type)
|
|
||||||
:type (pathname-type name-and-type)
|
|
||||||
:defaults pathname))
|
|
||||||
pathname)))
|
|
||||||
|
|
||||||
(defun walk-directory (dirname fn &key directories (test (constantly t)))
|
|
||||||
(labels
|
|
||||||
((walk (name)
|
|
||||||
(cond
|
|
||||||
((directory-pathname-p name)
|
|
||||||
(when (and directories (funcall test name))
|
|
||||||
(funcall fn name))
|
|
||||||
(dolist (x (list-directory name)) (walk x)))
|
|
||||||
((funcall test name) (funcall fn name)))))
|
|
||||||
(walk (pathname-as-directory dirname))))
|
|
||||||
|
|
|
@ -1,34 +0,0 @@
|
||||||
(ql:quickload :cl-cffi-gtk)
|
|
||||||
|
|
||||||
; Main window
|
|
||||||
(defvar window (make-instance 'gtk:gtk-window :type :toplevel :title "GTK Test"))
|
|
||||||
(defvar vbox (make-instance 'gtk:gtk-box :orientation :vertical
|
|
||||||
:spacing 10
|
|
||||||
:margin 10))
|
|
||||||
|
|
||||||
(defvar text-panel-box (make-instance 'gtk:gtk-box :orientation :horizontal :spacing 1 :margin 10))
|
|
||||||
(defvar panel-left-window (make-instance 'gtk:gtk-scrolled-window :height-request 500 :width-request 100))
|
|
||||||
(defvar panel-left (make-instance 'gtk:gtk-text-view :height-request 300 :width-request 100 :wrap-mode :word-char :vscroll-policy :natural))
|
|
||||||
(defvar panel-right-window (make-instance 'gtk:gtk-scrolled-window :height-request 500 :width-request 300))
|
|
||||||
(defvar panel-right (make-instance 'gtk:gtk-text-view :height-request 300 :width-request 300 :wrap-mode :word-char :vscroll-policy :natural))
|
|
||||||
|
|
||||||
(gtk:gtk-box-pack-start vbox text-panel-box)
|
|
||||||
(gtk:gtk-container-add panel-left-window panel-left)
|
|
||||||
(gtk:gtk-box-pack-start text-panel-box panel-left-window)
|
|
||||||
(gtk:gtk-container-add panel-right-window panel-right)
|
|
||||||
(gtk:gtk-box-pack-end text-panel-box panel-right-window)
|
|
||||||
|
|
||||||
(gtk:within-main-loop
|
|
||||||
; Quit program when window closed
|
|
||||||
(gobject:g-signal-connect window "destroy" (lambda (widget)
|
|
||||||
(declare (ignore widget))
|
|
||||||
(gtk:leave-gtk-main)))
|
|
||||||
; Display GUI
|
|
||||||
(gtk:gtk-container-add window vbox)
|
|
||||||
(gtk:gtk-widget-show-all window))
|
|
||||||
|
|
||||||
(loop
|
|
||||||
(sleep 3)
|
|
||||||
(setf (gtk:gtk-text-buffer-text (gtk:gtk-text-view-buffer panel-right)) (format nil "~a~a" (gtk:gtk-text-buffer-text (gtk:gtk-text-view-buffer panel-right)) "
|
|
||||||
Hello, world!
|
|
||||||
")))
|
|
|
@ -1,88 +0,0 @@
|
||||||
(ql:quickload '(clack websocket-driver alexandria))
|
|
||||||
|
|
||||||
(defvar *connections* (make-hash-table))
|
|
||||||
|
|
||||||
(defun handle-new-connection (con)
|
|
||||||
(setf (gethash con *connections*)
|
|
||||||
(format nil "user-~a" (random 100000))))
|
|
||||||
|
|
||||||
(defun broadcast-to-room (connection message)
|
|
||||||
(let ((message (format nil "~a: ~a"
|
|
||||||
(gethash connection *connections*)
|
|
||||||
message)))
|
|
||||||
(loop :for con :being :the :hash-key :of *connections* :do
|
|
||||||
(websocket-driver:send con message))))
|
|
||||||
|
|
||||||
(defun handle-close-connection (connection)
|
|
||||||
(let ((message (format nil " .... ~a has left."
|
|
||||||
(gethash connection *connections*))))
|
|
||||||
(remhash connection *connections*)
|
|
||||||
(loop :for con :being :the :hash-key :of *connections* :do
|
|
||||||
(websocket-driver:send con message))))
|
|
||||||
|
|
||||||
(defun chat-server (env)
|
|
||||||
(let ((ws (websocket-driver:make-server env)))
|
|
||||||
(websocket-driver:on :open ws
|
|
||||||
(lambda () (handle-new-connection ws)))
|
|
||||||
|
|
||||||
(websocket-driver:on :message ws
|
|
||||||
(lambda (msg)
|
|
||||||
(broadcast-to-room ws msg)))
|
|
||||||
|
|
||||||
(websocket-driver:on :close ws
|
|
||||||
(lambda (&key code reason)
|
|
||||||
(declare (ignore code reason))
|
|
||||||
(handle-close-connection ws)))
|
|
||||||
(lambda (responder)
|
|
||||||
(declare (ignore responder))
|
|
||||||
(websocket-driver:start-connection ws))))
|
|
||||||
|
|
||||||
(defvar *html*
|
|
||||||
"<!doctype html>
|
|
||||||
|
|
||||||
<html lang=\"en\">
|
|
||||||
<head>
|
|
||||||
<meta charset=\"utf-8\">
|
|
||||||
<title>LISP-CHAT</title>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<ul id=\"chat-echo-area\">
|
|
||||||
</ul>
|
|
||||||
<div style=\"position:fixed; bottom:0;\">
|
|
||||||
<input id=\"chat-input\" placeholder=\"say something\" >
|
|
||||||
</div>
|
|
||||||
<script>
|
|
||||||
window.onload = function () {
|
|
||||||
const inputField = document.getElementById(\"chat-input\");
|
|
||||||
|
|
||||||
function receivedMessage(msg) {
|
|
||||||
let li = document.createElement(\"li\");
|
|
||||||
li.textContent = msg.data;
|
|
||||||
document.getElementById(\"chat-echo-area\").appendChild(li);
|
|
||||||
}
|
|
||||||
|
|
||||||
const ws = new WebSocket(\"ws://localhost:12345/\");
|
|
||||||
ws.addEventListener('message', receivedMessage);
|
|
||||||
|
|
||||||
inputField.addEventListener(\"keyup\", (evt) => {
|
|
||||||
if (evt.key === \"Enter\") {
|
|
||||||
ws.send(evt.target.value);
|
|
||||||
evt.target.value = \"\";
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
")
|
|
||||||
|
|
||||||
(defun client-server (env)
|
|
||||||
(declare (ignore env))
|
|
||||||
`(200 (:content-type "text/html")
|
|
||||||
(,*html*)))
|
|
||||||
|
|
||||||
(defvar *chat-handler* (clack:clackup #'chat-server :port 12345))
|
|
||||||
(defvar *client-handler* (clack:clackup #'client-server :port 8080))
|
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 6.5 KiB |
Binary file not shown.
After Width: | Height: | Size: 1023 B |
Binary file not shown.
After Width: | Height: | Size: 992 B |
Binary file not shown.
After Width: | Height: | Size: 1004 B |
Binary file not shown.
After Width: | Height: | Size: 981 B |
|
@ -0,0 +1,271 @@
|
||||||
|
// SDL Experiment 19, Barra Ó Catháin.
|
||||||
|
// ===================================
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
|
#include <SDL2/SDL_image.h>
|
||||||
|
#include <SDL2/SDL_timer.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include "xyVector.h"
|
||||||
|
#include "spacewarPlayer.h"
|
||||||
|
|
||||||
|
void DrawCircle(SDL_Renderer * renderer, int32_t centreX, int32_t centreY, int32_t radius)
|
||||||
|
{
|
||||||
|
const int32_t diameter = (radius * 2);
|
||||||
|
|
||||||
|
int32_t x = (radius - 1);
|
||||||
|
int32_t y = 0;
|
||||||
|
int32_t tx = 1;
|
||||||
|
int32_t ty = 1;
|
||||||
|
int32_t error = (tx - diameter);
|
||||||
|
|
||||||
|
while (x >= y)
|
||||||
|
{
|
||||||
|
// Each of the following renders an octant of the circle
|
||||||
|
SDL_RenderDrawPoint(renderer, centreX + x, centreY - y);
|
||||||
|
SDL_RenderDrawPoint(renderer, centreX + x, centreY + y);
|
||||||
|
SDL_RenderDrawPoint(renderer, centreX - x, centreY - y);
|
||||||
|
SDL_RenderDrawPoint(renderer, centreX - x, centreY + y);
|
||||||
|
SDL_RenderDrawPoint(renderer, centreX + y, centreY - x);
|
||||||
|
SDL_RenderDrawPoint(renderer, centreX + y, centreY + x);
|
||||||
|
SDL_RenderDrawPoint(renderer, centreX - y, centreY - x);
|
||||||
|
SDL_RenderDrawPoint(renderer, centreX - y, centreY + x);
|
||||||
|
|
||||||
|
if (error <= 0)
|
||||||
|
{
|
||||||
|
++y;
|
||||||
|
error += ty;
|
||||||
|
ty += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error > 0)
|
||||||
|
{
|
||||||
|
--x;
|
||||||
|
tx += 2;
|
||||||
|
error += (tx - diameter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char ** argv)
|
||||||
|
{
|
||||||
|
SDL_Event event;
|
||||||
|
bool quit = false, rotatingClockwise = false, rotatingAnticlockwise = false, accelerating = false;
|
||||||
|
int width = 0, height = 0;
|
||||||
|
uint32_t rendererFlags = SDL_RENDERER_ACCELERATED;
|
||||||
|
uint64_t thisFrameTime = SDL_GetPerformanceCounter(), lastFrameTime = 0;
|
||||||
|
long positionX = 512, positionY = 512, starPositionX = 0, starPositionY = 0;
|
||||||
|
xyVector positionVector = {512, 512}, velocityVector = {1, 0}, gravityVector = {0, 0},
|
||||||
|
engineVector = {0.04, 0}, upVector = {0, 0.1}, starPosition = {0, 0};
|
||||||
|
|
||||||
|
// Create the socket:
|
||||||
|
int receiveSocket = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
if (receiveSocket < 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "\tSocket Creation is:\t\033[33;40mRED.\033[0m Aborting launch.\n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
printf("\tSocket Creation is:\t\033[32;40mGREEN.\033[0m\n");
|
||||||
|
|
||||||
|
// Make the socket timeout:
|
||||||
|
struct timeval read_timeout;
|
||||||
|
read_timeout.tv_sec = 0;
|
||||||
|
read_timeout.tv_usec = 16;
|
||||||
|
setsockopt(receiveSocket, SOL_SOCKET, SO_RCVTIMEO, &read_timeout, sizeof(read_timeout));
|
||||||
|
|
||||||
|
// Create and fill the information needed to bind to the socket:
|
||||||
|
struct sockaddr_in serverAddress;
|
||||||
|
memset(&serverAddress, 0, sizeof(serverAddress));
|
||||||
|
serverAddress.sin_family = AF_INET; // IPv4
|
||||||
|
serverAddress.sin_addr.s_addr = INADDR_ANY;
|
||||||
|
serverAddress.sin_port = htons(12000);
|
||||||
|
|
||||||
|
// Bind to the socket:
|
||||||
|
if (bind(receiveSocket, (const struct sockaddr *)&serverAddress, sizeof(serverAddress)) < 0)
|
||||||
|
{
|
||||||
|
perror("bind failed");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the socket:
|
||||||
|
int sendSocket = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
if (sendSocket < 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "\tSocket Creation is:\t\033[33;40mRED.\033[0m Aborting launch.\n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
printf("\tSocket Creation is:\t\033[32;40mGREEN.\033[0m\n");
|
||||||
|
|
||||||
|
|
||||||
|
// Create and fill the information needed to bind to the socket:
|
||||||
|
struct sockaddr_in sendAddress;
|
||||||
|
memset(&sendAddress, 0, sizeof(sendAddress));
|
||||||
|
sendAddress.sin_family = AF_INET; // IPv4
|
||||||
|
sendAddress.sin_addr.s_addr = inet_addr("127.0.0.1");
|
||||||
|
sendAddress.sin_port = htons(12001);
|
||||||
|
|
||||||
|
// Get the initial
|
||||||
|
ship shipA;
|
||||||
|
ship shipB;
|
||||||
|
|
||||||
|
// Initialize the SDL library, video, sound, and input:
|
||||||
|
if (SDL_Init(SDL_INIT_EVERYTHING) != 0)
|
||||||
|
{
|
||||||
|
printf("SDL Initialization Error: %s\n", SDL_GetError());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize image loading:
|
||||||
|
IMG_Init(IMG_INIT_PNG);
|
||||||
|
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "2");
|
||||||
|
|
||||||
|
// Create an SDL window and rendering context in that window:
|
||||||
|
SDL_Window * window = SDL_CreateWindow("SDL_TEST", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 700, 700, 0);
|
||||||
|
SDL_Renderer * renderer = SDL_CreateRenderer(window, -1, rendererFlags);
|
||||||
|
SDL_SetWindowTitle(window, "Spacewar!");
|
||||||
|
|
||||||
|
// Load in all of our textures:
|
||||||
|
SDL_Texture * idleTexture, * acceleratingTexture, * clockwiseTexture, * anticlockwiseTexture, * currentTexture,
|
||||||
|
* acceleratingTexture2;
|
||||||
|
|
||||||
|
idleTexture = IMG_LoadTexture(renderer, "./Images/Ship-Idle.png");
|
||||||
|
clockwiseTexture = IMG_LoadTexture(renderer, "./Images/Ship-Clockwise.png");
|
||||||
|
acceleratingTexture = IMG_LoadTexture(renderer, "./Images/Ship-Accelerating.png");
|
||||||
|
anticlockwiseTexture = IMG_LoadTexture(renderer, "./Images/Ship-Anticlockwise.png");
|
||||||
|
acceleratingTexture2 = IMG_LoadTexture(renderer, "./Images/Ship-Accelerating-Frame-2.png");
|
||||||
|
|
||||||
|
// Enable resizing the window:
|
||||||
|
SDL_SetWindowResizable(window, SDL_TRUE);
|
||||||
|
ship Temp;
|
||||||
|
playerController playerOne;
|
||||||
|
playerOne.number = 1;
|
||||||
|
bool shipAUpdated, shipBUpdated;
|
||||||
|
while (!quit)
|
||||||
|
{
|
||||||
|
while(!(shipAUpdated && shipBUpdated))
|
||||||
|
{
|
||||||
|
// Receive data from the socket:
|
||||||
|
recvfrom(receiveSocket, &Temp, sizeof(ship), 0, NULL, NULL);
|
||||||
|
if(Temp.number == 0)
|
||||||
|
{
|
||||||
|
shipA = Temp;
|
||||||
|
shipAUpdated = true;
|
||||||
|
}
|
||||||
|
if(Temp.number == 1)
|
||||||
|
{
|
||||||
|
shipB = Temp;
|
||||||
|
shipBUpdated = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the user wants to quit:
|
||||||
|
while (SDL_PollEvent(&event))
|
||||||
|
{
|
||||||
|
switch (event.type)
|
||||||
|
{
|
||||||
|
case SDL_QUIT:
|
||||||
|
{
|
||||||
|
quit = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SDL_KEYDOWN:
|
||||||
|
{
|
||||||
|
switch (event.key.keysym.sym)
|
||||||
|
{
|
||||||
|
case SDLK_LEFT:
|
||||||
|
{
|
||||||
|
playerOne.turningAnticlockwise = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SDLK_RIGHT:
|
||||||
|
{
|
||||||
|
playerOne.turningClockwise = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SDLK_UP:
|
||||||
|
{
|
||||||
|
playerOne.accelerating = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SDL_KEYUP:
|
||||||
|
{
|
||||||
|
switch (event.key.keysym.sym)
|
||||||
|
{
|
||||||
|
case SDLK_LEFT:
|
||||||
|
{
|
||||||
|
playerOne.turningAnticlockwise = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SDLK_RIGHT:
|
||||||
|
{
|
||||||
|
playerOne.turningClockwise = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SDLK_UP:
|
||||||
|
{
|
||||||
|
playerOne.accelerating = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sendto(sendSocket, &playerOne, sizeof(playerOne), 0, (const struct sockaddr *)&sendAddress, sizeof(sendAddress));
|
||||||
|
// Store the window's current width and height:
|
||||||
|
SDL_GetWindowSize(window, &width, &height);
|
||||||
|
|
||||||
|
// Set the texture to idle:
|
||||||
|
currentTexture = idleTexture;
|
||||||
|
|
||||||
|
// Calculate the position of the sprites:
|
||||||
|
shipB.rectangle.x = (width/2) - 16 - (shipB.velocity.xComponent * 15);
|
||||||
|
shipB.rectangle.y = (height/2) - 16 - (shipB.velocity.yComponent * 15);
|
||||||
|
|
||||||
|
shipA.rectangle.x = (long)((((shipA.position.xComponent - shipB.position.xComponent) - 32) + width/2) - (shipB.velocity.xComponent * 15));
|
||||||
|
shipA.rectangle.y = (long)((((shipA.position.yComponent - shipB.position.yComponent) - 32) + height/2) - (shipB.velocity.yComponent * 15));
|
||||||
|
|
||||||
|
// Set the colour to black:
|
||||||
|
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
|
||||||
|
|
||||||
|
// Clear the screen, filling it with black:
|
||||||
|
SDL_RenderClear(renderer);
|
||||||
|
|
||||||
|
// Draw the ship:
|
||||||
|
SDL_RenderCopyEx(renderer, currentTexture, NULL, &shipA.rectangle,
|
||||||
|
angleBetweenVectors(&shipA.engine, &upVector) + 90, NULL, 0);
|
||||||
|
SDL_RenderCopyEx(renderer, currentTexture, NULL, &shipB.rectangle,
|
||||||
|
angleBetweenVectors(&shipB.engine, &upVector) + 90, NULL, 0);
|
||||||
|
|
||||||
|
// Set the colour to yellow:
|
||||||
|
SDL_SetRenderDrawColor(renderer, 255, 255, 0, 255);
|
||||||
|
|
||||||
|
// Draw a circle as the star:
|
||||||
|
DrawCircle(renderer, (long)(starPositionX - shipB.position.xComponent) + width/2 - (shipB.velocity.xComponent * 15),
|
||||||
|
(long)(starPositionY - shipB.position.yComponent) + height/2 - (shipB.velocity.yComponent * 15), 50);
|
||||||
|
|
||||||
|
// Present the rendered graphics:
|
||||||
|
SDL_RenderPresent(renderer);
|
||||||
|
shipAUpdated = false;
|
||||||
|
shipBUpdated = false;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// ========================================================================================================
|
||||||
|
// Local Variables:
|
||||||
|
// compile-command: "gcc `sdl2-config --libs --cflags` SDL2-Experiment-19-Client.c -lSDL2_image -lm -o 'Spacewar Client!'"
|
||||||
|
// End:
|
|
@ -0,0 +1,474 @@
|
||||||
|
// SDL Experiment 19, Barra Ó Catháin.
|
||||||
|
// ===================================
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
|
#include <SDL2/SDL_image.h>
|
||||||
|
#include <SDL2/SDL_timer.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include "xyVector.h"
|
||||||
|
#include "spacewarPlayer.h"
|
||||||
|
|
||||||
|
void DrawCircle(SDL_Renderer * renderer, int32_t centreX, int32_t centreY, int32_t radius)
|
||||||
|
{
|
||||||
|
const int32_t diameter = (radius * 2);
|
||||||
|
|
||||||
|
int32_t x = (radius - 1);
|
||||||
|
int32_t y = 0;
|
||||||
|
int32_t tx = 1;
|
||||||
|
int32_t ty = 1;
|
||||||
|
int32_t error = (tx - diameter);
|
||||||
|
|
||||||
|
while (x >= y)
|
||||||
|
{
|
||||||
|
// Each of the following renders an octant of the circle
|
||||||
|
SDL_RenderDrawPoint(renderer, centreX + x, centreY - y);
|
||||||
|
SDL_RenderDrawPoint(renderer, centreX + x, centreY + y);
|
||||||
|
SDL_RenderDrawPoint(renderer, centreX - x, centreY - y);
|
||||||
|
SDL_RenderDrawPoint(renderer, centreX - x, centreY + y);
|
||||||
|
SDL_RenderDrawPoint(renderer, centreX + y, centreY - x);
|
||||||
|
SDL_RenderDrawPoint(renderer, centreX + y, centreY + x);
|
||||||
|
SDL_RenderDrawPoint(renderer, centreX - y, centreY - x);
|
||||||
|
SDL_RenderDrawPoint(renderer, centreX - y, centreY + x);
|
||||||
|
|
||||||
|
if (error <= 0)
|
||||||
|
{
|
||||||
|
++y;
|
||||||
|
error += ty;
|
||||||
|
ty += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error > 0)
|
||||||
|
{
|
||||||
|
--x;
|
||||||
|
tx += 2;
|
||||||
|
error += (tx - diameter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void calculateGravity(xyVector * starPosition, ship * shipUnderGravity)
|
||||||
|
{
|
||||||
|
// Calculate the vector between the star and ship:
|
||||||
|
xyVectorBetweenPoints(shipUnderGravity->position.xComponent, shipUnderGravity->position.yComponent,
|
||||||
|
starPosition->xComponent, starPosition->yComponent, &shipUnderGravity->gravity);
|
||||||
|
|
||||||
|
// Make it into a unit vector:
|
||||||
|
double gravityMagnitude = normalizeXYVector(&shipUnderGravity->gravity);
|
||||||
|
double gravityAcceleration = 0;
|
||||||
|
|
||||||
|
// Calculate the gravity between the star and ship:
|
||||||
|
if(gravityMagnitude != 0)
|
||||||
|
{
|
||||||
|
if(gravityMagnitude >= 116)
|
||||||
|
{
|
||||||
|
gravityAcceleration = pow(2, (3000 / (pow(gravityMagnitude, 2)))) / 8;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gravityAcceleration = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gravityAcceleration = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(gravityAcceleration < 0.01)
|
||||||
|
{
|
||||||
|
gravityAcceleration = 0.01;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scale the vector:
|
||||||
|
multiplyXYVector(&shipUnderGravity->gravity, gravityAcceleration);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a ship with the given parameters:
|
||||||
|
ship createShip(int width, int height, double positionX, double positionY, double velocityX, double velocityY, int number)
|
||||||
|
{
|
||||||
|
ship newShip;
|
||||||
|
|
||||||
|
// Player number:
|
||||||
|
newShip.number = number;
|
||||||
|
|
||||||
|
// Rectangle to show the ship in:
|
||||||
|
newShip.rectangle.w = width;
|
||||||
|
newShip.rectangle.h = height;
|
||||||
|
|
||||||
|
// Position:
|
||||||
|
newShip.position.xComponent = positionX;
|
||||||
|
newShip.position.yComponent = positionY;
|
||||||
|
|
||||||
|
// Velocity:
|
||||||
|
newShip.velocity.xComponent = velocityX;
|
||||||
|
newShip.velocity.yComponent = velocityY;
|
||||||
|
|
||||||
|
// Gravity:
|
||||||
|
newShip.gravity.xComponent = 0;
|
||||||
|
newShip.gravity.yComponent = 0;
|
||||||
|
|
||||||
|
// Engine:
|
||||||
|
newShip.engine.yComponent = 0;
|
||||||
|
newShip.engine.xComponent = 0.1;
|
||||||
|
return newShip;
|
||||||
|
}
|
||||||
|
|
||||||
|
playerController createShipPlayerController(ship * ship)
|
||||||
|
{
|
||||||
|
playerController newController;
|
||||||
|
newController.number = ship->number;
|
||||||
|
return newController;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void takeNetworkInput(playerController * controller, int descriptor)
|
||||||
|
{
|
||||||
|
recvfrom(descriptor, controller, sizeof(playerController), 0, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline void getPlayerInput(playerController * controller, int playerNumber)
|
||||||
|
{
|
||||||
|
SDL_PumpEvents();
|
||||||
|
const uint8_t * keyboardState = SDL_GetKeyboardState(NULL);
|
||||||
|
if(keyboardState[SDL_SCANCODE_UP] == 1)
|
||||||
|
{
|
||||||
|
controller->accelerating = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
controller->accelerating = false;
|
||||||
|
}
|
||||||
|
if(keyboardState[SDL_SCANCODE_LEFT] == 1)
|
||||||
|
{
|
||||||
|
controller->turningAnticlockwise = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
controller->turningAnticlockwise = false;;
|
||||||
|
}
|
||||||
|
if(keyboardState[SDL_SCANCODE_RIGHT] == 1)
|
||||||
|
{
|
||||||
|
controller->turningClockwise = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
controller->turningClockwise = false;
|
||||||
|
}
|
||||||
|
if(controller->joystick != NULL)
|
||||||
|
{
|
||||||
|
controller->turningAmount = SDL_JoystickGetAxis(controller->joystick, 0);
|
||||||
|
controller->acceleratingAmount = SDL_JoystickGetAxis(controller->joystick, 5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void doShipInput(playerController * controller, ship * ship, xyVector starPosition, double deltaTime)
|
||||||
|
{
|
||||||
|
if(controller->number == ship->number)
|
||||||
|
{
|
||||||
|
// Calculate the gravity for the ships:
|
||||||
|
calculateGravity(&starPosition, ship);
|
||||||
|
|
||||||
|
// Rotate the engine vector if needed:
|
||||||
|
if (controller->turningClockwise)
|
||||||
|
{
|
||||||
|
rotateXYVector(&ship->engine, 0.25 * deltaTime);
|
||||||
|
}
|
||||||
|
else if (controller->turningAmount > 2500)
|
||||||
|
{
|
||||||
|
double rotationalSpeed = (controller->turningAmount / 20000);
|
||||||
|
rotateXYVector(&ship->engine, 0.25 * deltaTime * rotationalSpeed);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (controller->turningAnticlockwise)
|
||||||
|
{
|
||||||
|
rotateXYVector(&ship->engine, -0.25 * deltaTime);
|
||||||
|
}
|
||||||
|
else if (controller->turningAmount < -2500)
|
||||||
|
{
|
||||||
|
double rotationalSpeed = (controller->turningAmount / 20000);
|
||||||
|
rotateXYVector(&ship->engine, 0.25 * deltaTime * rotationalSpeed);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate the new current velocity:
|
||||||
|
addXYVectorDeltaScaled(&ship->velocity, &ship->gravity, deltaTime);
|
||||||
|
|
||||||
|
if (controller->acceleratingAmount > 2500)
|
||||||
|
{
|
||||||
|
xyVector temporary = ship->engine;
|
||||||
|
multiplyXYVector(&ship->engine, controller->acceleratingAmount/ 32748);
|
||||||
|
SDL_HapticRumblePlay(controller->haptic, (float)controller->acceleratingAmount / 32768, 20);
|
||||||
|
addXYVectorDeltaScaled(&ship->velocity, &ship->engine, deltaTime);
|
||||||
|
ship->engine = temporary;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (controller->accelerating)
|
||||||
|
{
|
||||||
|
addXYVectorDeltaScaled(&ship->velocity, &ship->engine, deltaTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate the new position:
|
||||||
|
addXYVectorDeltaScaled(&ship->position, &ship->velocity, deltaTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char ** argv)
|
||||||
|
{
|
||||||
|
SDL_Event event;
|
||||||
|
int width = 0, height = 0;
|
||||||
|
uint32_t rendererFlags = SDL_RENDERER_ACCELERATED;
|
||||||
|
uint64_t thisFrameTime = SDL_GetPerformanceCounter(), lastFrameTime = 0;
|
||||||
|
long starPositionX = 0, starPositionY = 0;
|
||||||
|
double deltaTime = 0, frameAccumulator = 0;
|
||||||
|
bool quit = false, rotatingClockwise = false, rotatingAnticlockwise = false, accelerating = false;
|
||||||
|
xyVector engineVector = {0.85, 0}, upVector = {0, 0.1}, starPosition = {0, 0};
|
||||||
|
|
||||||
|
// Create the socket:
|
||||||
|
int sendSocket = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
if (sendSocket < 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "\tSocket Creation is:\t\033[33;40mRED.\033[0m Aborting launch.\n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
printf("\tSocket Creation is:\t\033[32;40mGREEN.\033[0m\n");
|
||||||
|
|
||||||
|
// Create and fill the information needed to bind to the socket:
|
||||||
|
struct sockaddr_in sendAddress;
|
||||||
|
sendAddress.sin_family = AF_INET; // IPv4
|
||||||
|
sendAddress.sin_addr.s_addr = inet_addr("127.0.0.1");
|
||||||
|
sendAddress.sin_port = htons(12000);
|
||||||
|
|
||||||
|
int receiveSocket = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
if (receiveSocket < 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "\tSocket Creation is:\t\033[33;40mRED.\033[0m Aborting launch.\n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
printf("\tSocket Creation is:\t\033[32;40mGREEN.\033[0m\n");
|
||||||
|
|
||||||
|
// Make the socket timeout:
|
||||||
|
struct timeval readTimeout;
|
||||||
|
readTimeout.tv_sec = 0;
|
||||||
|
readTimeout.tv_usec = 800;
|
||||||
|
setsockopt(receiveSocket, SOL_SOCKET, SO_RCVTIMEO, &readTimeout, sizeof(readTimeout));
|
||||||
|
|
||||||
|
// Create and fill the information needed to bind to the socket:
|
||||||
|
struct sockaddr_in receiveAddress;
|
||||||
|
memset(&receiveAddress, 0, sizeof(receiveAddress));
|
||||||
|
receiveAddress.sin_family = AF_INET; // IPv4
|
||||||
|
receiveAddress.sin_addr.s_addr = INADDR_ANY;
|
||||||
|
receiveAddress.sin_port = htons(12001);
|
||||||
|
|
||||||
|
// Bind to the socket:
|
||||||
|
if (bind(receiveSocket, (const struct sockaddr *)&receiveAddress, sizeof(receiveAddress)) < 0)
|
||||||
|
{
|
||||||
|
perror("bind failed");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
ship shipA = createShip(32, 32, 512, 512, 1, 0, 0);
|
||||||
|
ship shipB = createShip(32, 32, -512, -512, 0, 1, 1);
|
||||||
|
|
||||||
|
// Initialize the SDL library, video, sound, and input:
|
||||||
|
if (SDL_Init(SDL_INIT_EVERYTHING) != 0)
|
||||||
|
{
|
||||||
|
printf("SDL Initialization Error: %s\n", SDL_GetError());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize image loading:
|
||||||
|
IMG_Init(IMG_INIT_PNG);
|
||||||
|
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "2");
|
||||||
|
SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1");
|
||||||
|
|
||||||
|
playerController playerOne = createShipPlayerController(&shipA);
|
||||||
|
playerController playerTwo = createShipPlayerController(&shipB);
|
||||||
|
|
||||||
|
// Check for joysticks:
|
||||||
|
if (SDL_NumJoysticks() < 1 )
|
||||||
|
{
|
||||||
|
printf( "Warning: No joysticks connected!\n" );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Load all joysticks:
|
||||||
|
int joystickListLength = SDL_NumJoysticks();
|
||||||
|
SDL_Joystick ** joysticksList = calloc(joystickListLength, sizeof(SDL_Joystick*));
|
||||||
|
|
||||||
|
for(int index = 0; index < SDL_NumJoysticks(); index++)
|
||||||
|
{
|
||||||
|
joysticksList[index] = SDL_JoystickOpen(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Choose a player joystick:
|
||||||
|
printf("Please press button zero on the controller you wish to use. \n");
|
||||||
|
|
||||||
|
int joystickIndex = 0;
|
||||||
|
while(SDL_JoystickGetButton(joysticksList[joystickIndex], 0) == 0)
|
||||||
|
{
|
||||||
|
SDL_PumpEvents();
|
||||||
|
joystickIndex++;
|
||||||
|
if(joystickIndex >= joystickListLength)
|
||||||
|
{
|
||||||
|
joystickIndex = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load joystick
|
||||||
|
playerOne.joystick = joysticksList[joystickIndex];
|
||||||
|
if (playerOne.joystick == NULL )
|
||||||
|
{
|
||||||
|
printf( "Warning: Unable to open game controller! SDL Error: %s\n", SDL_GetError() );
|
||||||
|
}
|
||||||
|
playerOne.haptic = SDL_HapticOpenFromJoystick(playerOne.joystick);
|
||||||
|
SDL_HapticRumbleInit(playerOne.haptic);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create an SDL window and rendering context in that window:
|
||||||
|
SDL_Window * window = SDL_CreateWindow("SDL_TEST", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 700, 700, 0);
|
||||||
|
SDL_Renderer * renderer = SDL_CreateRenderer(window, -1, rendererFlags);
|
||||||
|
SDL_SetWindowTitle(window, "Spacewar!");
|
||||||
|
|
||||||
|
// Load in all of our textures:
|
||||||
|
SDL_Texture * idleTexture, * acceleratingTexture, * clockwiseTexture, * anticlockwiseTexture, * currentTexture,
|
||||||
|
* acceleratingTexture2;
|
||||||
|
|
||||||
|
idleTexture = IMG_LoadTexture(renderer, "./Images/Ship-Idle.png");
|
||||||
|
clockwiseTexture = IMG_LoadTexture(renderer, "./Images/Ship-Clockwise.png");
|
||||||
|
acceleratingTexture = IMG_LoadTexture(renderer, "./Images/Ship-Accelerating.png");
|
||||||
|
anticlockwiseTexture = IMG_LoadTexture(renderer, "./Images/Ship-Anticlockwise.png");
|
||||||
|
acceleratingTexture2 = IMG_LoadTexture(renderer, "./Images/Ship-Accelerating-Frame-2.png");
|
||||||
|
currentTexture = acceleratingTexture;
|
||||||
|
|
||||||
|
// Enable resizing the window:
|
||||||
|
SDL_SetWindowResizable(window, SDL_TRUE);
|
||||||
|
|
||||||
|
lastFrameTime = SDL_GetPerformanceCounter();
|
||||||
|
thisFrameTime = SDL_GetPerformanceCounter();
|
||||||
|
|
||||||
|
while (!quit)
|
||||||
|
{
|
||||||
|
lastFrameTime = thisFrameTime;
|
||||||
|
thisFrameTime = SDL_GetPerformanceCounter();
|
||||||
|
deltaTime = (double)(((thisFrameTime - lastFrameTime) * 1000) / (double)SDL_GetPerformanceFrequency());
|
||||||
|
|
||||||
|
sendto(sendSocket, &shipA, sizeof(ship), 0, (const struct sockaddr *)&sendAddress, sizeof(sendAddress));
|
||||||
|
sendto(sendSocket, &shipB, sizeof(ship), 0, (const struct sockaddr *)&sendAddress, sizeof(sendAddress));
|
||||||
|
// Store the window's current width and height:
|
||||||
|
SDL_GetWindowSize(window, &width, &height);
|
||||||
|
|
||||||
|
// Check input:
|
||||||
|
while (SDL_PollEvent(&event))
|
||||||
|
{
|
||||||
|
switch (event.type)
|
||||||
|
{
|
||||||
|
case SDL_QUIT:
|
||||||
|
{
|
||||||
|
quit = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wrap the positions if the ship goes interstellar:
|
||||||
|
if(shipA.position.xComponent > 4096)
|
||||||
|
{
|
||||||
|
shipA.position.xComponent = -2000;
|
||||||
|
}
|
||||||
|
else if(shipA.position.xComponent < -4096)
|
||||||
|
{
|
||||||
|
shipA.position.xComponent = 2000;
|
||||||
|
}
|
||||||
|
if(shipA.position.yComponent > 4096)
|
||||||
|
{
|
||||||
|
shipA.position.yComponent = -2000;
|
||||||
|
}
|
||||||
|
else if(shipA.position.yComponent < -4096)
|
||||||
|
{
|
||||||
|
shipA.position.yComponent = 2000;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(shipB.position.xComponent > 4096)
|
||||||
|
{
|
||||||
|
shipB.position.xComponent = -2000;
|
||||||
|
shipB.velocity.xComponent *= 0.9;
|
||||||
|
}
|
||||||
|
else if(shipB.position.xComponent < -4096)
|
||||||
|
{
|
||||||
|
shipB.position.xComponent = 2000;
|
||||||
|
shipB.velocity.xComponent *= 0.9;
|
||||||
|
}
|
||||||
|
if(shipB.position.yComponent > 4096)
|
||||||
|
{
|
||||||
|
shipB.position.yComponent = -2000;
|
||||||
|
shipB.velocity.yComponent *= 0.9;
|
||||||
|
}
|
||||||
|
else if(shipB.position.yComponent < -4096)
|
||||||
|
{
|
||||||
|
shipB.position.yComponent = 2000;
|
||||||
|
shipB.velocity.yComponent *= 0.9;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the needed input:
|
||||||
|
getPlayerInput(&playerOne, 0);
|
||||||
|
takeNetworkInput(&playerTwo, receiveSocket);
|
||||||
|
|
||||||
|
// Do the needed input:
|
||||||
|
doShipInput(&playerOne, &shipA, starPosition, deltaTime);
|
||||||
|
doShipInput(&playerTwo, &shipB, starPosition, deltaTime);
|
||||||
|
|
||||||
|
shipA.rectangle.x = (width/2) - 16 - (shipA.velocity.xComponent * 15);
|
||||||
|
shipA.rectangle.y = (height/2) - 16 - (shipA.velocity.yComponent * 15);
|
||||||
|
|
||||||
|
shipB.rectangle.x = (long)((((shipB.position.xComponent - shipA.position.xComponent) - 32) + width/2) - (shipA.velocity.xComponent * 15));
|
||||||
|
shipB.rectangle.y = (long)((((shipB.position.yComponent - shipA.position.yComponent) - 32) + height/2) - (shipA.velocity.yComponent * 15));
|
||||||
|
|
||||||
|
|
||||||
|
// Set the colour to black:
|
||||||
|
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
|
||||||
|
|
||||||
|
// Clear the screen, filling it with black:
|
||||||
|
SDL_RenderClear(renderer);
|
||||||
|
|
||||||
|
// Draw the ship:
|
||||||
|
SDL_RenderCopyEx(renderer, currentTexture, NULL, &shipA.rectangle,
|
||||||
|
angleBetweenVectors(&shipA.engine, &upVector) + 90, NULL, 0);
|
||||||
|
SDL_RenderCopyEx(renderer, currentTexture, NULL, &shipB.rectangle,
|
||||||
|
angleBetweenVectors(&shipB.engine, &upVector) + 90, NULL, 0);
|
||||||
|
|
||||||
|
// Set the colour to yellow:
|
||||||
|
SDL_SetRenderDrawColor(renderer, 255, 255, 0, 255);
|
||||||
|
|
||||||
|
// Draw a circle as the star:
|
||||||
|
DrawCircle(renderer, (long)(starPositionX - shipA.position.xComponent) + width/2 - (shipA.velocity.xComponent * 15),
|
||||||
|
(long)(starPositionY - shipA.position.yComponent) + height/2 - (shipA.velocity.yComponent * 15), 50);
|
||||||
|
|
||||||
|
// Draw a line representing the velocity:
|
||||||
|
SDL_RenderDrawLine(renderer, width/2 - (shipA.velocity.xComponent * 15),
|
||||||
|
height/2 - (shipA.velocity.yComponent * 15),
|
||||||
|
(long)((width/2) + shipA.velocity.xComponent * 15) - (shipA.velocity.xComponent * 15),
|
||||||
|
(long)((height/2) + shipA.velocity.yComponent * 15) - (shipA.velocity.yComponent * 15));
|
||||||
|
|
||||||
|
// Set the colour to blue:
|
||||||
|
SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255);
|
||||||
|
|
||||||
|
// Draw a line representing the direction of the star:
|
||||||
|
normalizeXYVector(&shipA.gravity);
|
||||||
|
multiplyXYVector(&shipA.gravity, 100);
|
||||||
|
SDL_RenderDrawLine(renderer,
|
||||||
|
width/2 - (shipA.velocity.xComponent * 15),
|
||||||
|
height/2 - (shipA.velocity.yComponent * 15),
|
||||||
|
(width/2 - (shipA.velocity.xComponent * 15)) + shipA.gravity.xComponent,
|
||||||
|
((height/2) - (shipA.velocity.yComponent * 15)) + shipA.gravity.yComponent);
|
||||||
|
|
||||||
|
// Present the rendered graphics:
|
||||||
|
SDL_RenderPresent(renderer);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// ========================================================================================================
|
||||||
|
// Local Variables:
|
||||||
|
// compile-command: "gcc `sdl2-config --libs --cflags` SDL2-Experiment-19.c -lSDL2_image -lm -o 'Spacewar!'"
|
||||||
|
// End:
|
|
@ -0,0 +1,26 @@
|
||||||
|
#ifndef SPACEWARPLAYER_H
|
||||||
|
#define SPACEWARPLAYER_H
|
||||||
|
#include "xyVector.h"
|
||||||
|
|
||||||
|
// A struct storing the needed data to draw a ship:
|
||||||
|
typedef struct ship
|
||||||
|
{
|
||||||
|
int number;
|
||||||
|
xyVector engine;
|
||||||
|
xyVector gravity;
|
||||||
|
xyVector position;
|
||||||
|
xyVector velocity;
|
||||||
|
SDL_Rect rectangle;
|
||||||
|
} ship;
|
||||||
|
|
||||||
|
// A struct to store the input state for one player:
|
||||||
|
typedef struct playerController
|
||||||
|
{
|
||||||
|
SDL_Joystick * joystick;
|
||||||
|
SDL_Haptic * haptic;
|
||||||
|
int number;
|
||||||
|
double turningAmount, acceleratingAmount;
|
||||||
|
bool turningClockwise, turningAnticlockwise, accelerating;
|
||||||
|
} playerController;
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,68 @@
|
||||||
|
#ifndef XYVECTOR_H
|
||||||
|
#define XYVECTOR_H
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
// A 2D vector:
|
||||||
|
typedef struct xyVector
|
||||||
|
{
|
||||||
|
double xComponent;
|
||||||
|
double yComponent;
|
||||||
|
} xyVector;
|
||||||
|
|
||||||
|
static inline double angleBetweenVectors(xyVector * vectorA, xyVector * vectorB)
|
||||||
|
{
|
||||||
|
double dotProduct = (vectorA->xComponent * vectorB->xComponent) + (vectorA->yComponent * vectorB->yComponent);
|
||||||
|
double determinant = (vectorA->xComponent * vectorB->yComponent) - (vectorA->yComponent * vectorB->xComponent);
|
||||||
|
|
||||||
|
return atan2(dotProduct, determinant) / 0.01745329;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate the vector from point A to point B:
|
||||||
|
static inline void xyVectorBetweenPoints(long ax, long ay, long bx, long by, xyVector * vector)
|
||||||
|
{
|
||||||
|
vector->xComponent = bx - ax;
|
||||||
|
vector->yComponent = by - ay;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Normalize a vector, returning the magnitude:
|
||||||
|
static inline double normalizeXYVector(xyVector * vector)
|
||||||
|
{
|
||||||
|
double magnitude = sqrt(pow(vector->xComponent, 2) + pow(vector->yComponent, 2));
|
||||||
|
if(magnitude != 0)
|
||||||
|
{
|
||||||
|
vector->xComponent /= magnitude;
|
||||||
|
vector->yComponent /= magnitude;
|
||||||
|
}
|
||||||
|
return magnitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rotate XY vector by a given number of degrees:
|
||||||
|
static inline void rotateXYVector(xyVector * vector, double degrees)
|
||||||
|
{
|
||||||
|
double xComponent = vector->xComponent, yComponent = vector->yComponent;
|
||||||
|
vector->xComponent = (cos(degrees * 0.01745329) * xComponent) - (sin(degrees * 0.01745329) * yComponent);
|
||||||
|
vector->yComponent = (sin(degrees * 0.01745329) * xComponent) + (cos(degrees * 0.01745329) * yComponent);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add vector B to vector A:
|
||||||
|
static inline void addXYVector(xyVector * vectorA, xyVector * vectorB)
|
||||||
|
{
|
||||||
|
vectorA->xComponent += vectorB->xComponent;
|
||||||
|
vectorA->yComponent += vectorB->yComponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add vector B to vector A, scaled for units per frame:
|
||||||
|
static inline void addXYVectorDeltaScaled(xyVector * vectorA, xyVector * vectorB, double deltaTime)
|
||||||
|
{
|
||||||
|
vectorA->xComponent += vectorB->xComponent * (0.001 * deltaTime) * 60;
|
||||||
|
vectorA->yComponent += vectorB->yComponent * (0.001 * deltaTime) * 60;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Multiply a vector by a scalar constant:
|
||||||
|
static inline void multiplyXYVector(xyVector * vector, double scalar)
|
||||||
|
{
|
||||||
|
vector->xComponent *= scalar;
|
||||||
|
vector->yComponent *= scalar;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,29 +0,0 @@
|
||||||
#!/usr/bin/guile -s
|
|
||||||
!#
|
|
||||||
(use-modules (sdl2)
|
|
||||||
(sdl2 render)
|
|
||||||
(sdl2 surface)
|
|
||||||
(sdl2 video)
|
|
||||||
(sdl2 image)
|
|
||||||
(sdl2 events)
|
|
||||||
(sdl2 input keyboard))
|
|
||||||
|
|
||||||
(define (draw renderer)
|
|
||||||
(set-renderer-draw-color! renderer 255 255 255 255)
|
|
||||||
|
|
||||||
(let* ((surface (load-image "guile.png"))
|
|
||||||
(texture (surface->texture renderer surface)))
|
|
||||||
|
|
||||||
(do ((event (poll-event) (poll-event)))
|
|
||||||
((eq? '#t (quit-event? event)))
|
|
||||||
(clear-renderer renderer)
|
|
||||||
(render-copy renderer texture)
|
|
||||||
(present-renderer renderer))))
|
|
||||||
|
|
||||||
(sdl-init)
|
|
||||||
|
|
||||||
(call-with-window (make-window)
|
|
||||||
(lambda (window)
|
|
||||||
(call-with-renderer (make-renderer window) draw)))
|
|
||||||
|
|
||||||
(sdl-quit)
|
|
Binary file not shown.
Before Width: | Height: | Size: 14 KiB |
|
@ -1,10 +0,0 @@
|
||||||
(define-module (barra infinite-loop))
|
|
||||||
|
|
||||||
(define-syntax infinite-loop
|
|
||||||
(syntax-rules ()
|
|
||||||
((infinite-loop procedure)
|
|
||||||
(do () (#f)
|
|
||||||
procedure))))
|
|
||||||
|
|
||||||
|
|
||||||
(export infinite-loop)
|
|
Loading…
Reference in New Issue