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