[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v2] modules: reparieren von Pong
+ Mit dem Programm Pong kann man jetzt wirklich Pong spielen!
---
src/modules/c/pong/main.c | 349 ++++++++++++++++++++++++++++++++------
1 file changed, 294 insertions(+), 55 deletions(-)
diff --git a/src/modules/c/pong/main.c b/src/modules/c/pong/main.c
index 0773dc21..14e2a0cd 100644
--- a/src/modules/c/pong/main.c
+++ b/src/modules/c/pong/main.c
@@ -33,15 +33,271 @@
#include <syscall.h>
#include <types.h>
#include <unistd.h>
+#include <init.h>
+#include <kbd.h>
+#include <lostio.h>
-int main(int argc, char** argv)
+#ifndef KEYCODE_ARROW_UP
+# define KEYCODE_ARROW_UP 103
+#endif
+
+#ifndef KEYCODE_ARROW_DOWN
+# define KEYCODE_ARROW_DOWN 108
+#endif
+
+#ifndef KEYCODE_ENTER
+# define KEYCODE_ENTER 28
+#endif
+
+#ifndef KEYCODE_ESC
+# define KEYCODE_ESC 1
+#endif
+
+//------------------------------------------------------------------------------
+// Types und Structs
+//------------------------------------------------------------------------------
+
+typedef struct Vector2 {
+ int x;
+ int y;
+} Vector2;
+
+typedef struct Player {
+ Vector2 position;
+ Vector2 size;
+ int lives;
+} Player;
+
+typedef struct Ball {
+ Vector2 position;
+ Vector2 speed;
+ Vector2 size;
+ bool active;
+} Ball;
+
+typedef struct Key {
+ bool down;
+ bool pressed;
+} Key;
+
+typedef struct Keyboard {
+ pid_t kbc_pid;
+ Key arrow_up;
+ Key arrow_down;
+ Key enter;
+ Key escape;
+} Keyboard;
+
+//------------------------------------------------------------------------------
+// Gloable Variablen
+//------------------------------------------------------------------------------
+
+static const int screen_width = 640;
+static const int screen_height = 480;
+static const int time_per_frame = 20 * 1000; // 20ms
+static const int player_max_live = 5;
+
+static bool game_over = false;
+
+static Player player = {0};
+static Ball ball = {0};
+static Keyboard keyboard = {0};
+
+static video_bitmap_t* front;
+
+//------------------------------------------------------------------------------
+// Funktions Definitionen
+//------------------------------------------------------------------------------
+
+static void update_key(Key* key, bool down)
+{
+ if (!down && key->down) {
+ key->pressed = true;
+ }
+
+ key->down = down;
+}
+
+static bool is_key_pressed(Key* key)
+{
+ if (key->pressed) {
+ key->pressed = false;
+ return true;
+ }
+
+ return false;
+}
+
+static void update_player(void)
+{
+ if (is_key_pressed(&keyboard.escape)) {
+ game_over = true;
+ }
+
+ if (!game_over) {
+ if (player.lives <= 0) {
+ game_over = true;
+ }
+ if (keyboard.arrow_up.down) {
+ player.position.y -= 5;
+ }
+ if (keyboard.arrow_down.down) {
+ player.position.y += 5;
+ }
+ if ((player.position.y + player.size.y) >= screen_height) {
+ player.position.y = screen_height - player.size.y;
+ }
+ if (player.position.y <= 0) {
+ player.position.y = 0;
+ }
+ }
+}
+
+static void update_ball(void)
+{
+ if (!game_over)
+ {
+ if (is_key_pressed(&keyboard.enter) && !ball.active) {
+ ball.speed = (Vector2){5,0};
+ ball.active = true;
+ }
+ if (ball.active) {
+ ball.position.x += ball.speed.x;
+ ball.position.y += ball.speed.y;
+ }
+ if ((ball.position.y + ball.size.y) >= screen_height ||
+ ball.position.y <= 0)
+ {
+ ball.speed.y = -ball.speed.y;
+ }
+
+ if ((ball.position.x + ball.size.x) >= screen_width) {
+ ball.speed.x = -ball.speed.x;
+ }
+
+ // Tooooor!
+ if (ball.position.x <= 0) {
+ ball.position = (Vector2){screen_width/2, screen_height/2};
+ ball.speed = (Vector2){0, 0};
+ ball.active = false;
+ player.lives--;
+ }
+
+ // kollision mit Spieler
+ // Der Ball kann auch von schräg oben bzw. schräg unten kommen.
+ // Daher wird der gesamte Kollisonsbereich überprüft.
+ if (player.position.x - ball.size.x <= ball.position.x &&
+ player.position.x + player.size.x >= ball.position.x &&
+ player.position.y - ball.size.y <= ball.position.y &&
+ player.position.y + player.size.y >= ball.position.y)
+ {
+ if (ball.speed.x < 0) {
+ ball.speed.x = -ball.speed.x;
+ }
+
+ // Erhöhen der Geschwindigkeit
+ // und damit auch der Schwierigkeitsgrad
+ if (ball.speed.y > 0) {
+ ball.speed.y += 1;
+ }
+ else {
+ ball.speed.y -= 1;
+ }
+
+ ball.speed.x += 1;
+ }
+ }
+}
+
+static void render(void)
+{
+ // Male Hintergrund
+ libvideo_change_color(0, 0, 0, 0);
+ libvideo_draw_rectangle(0, 0, screen_width, screen_height);
+
+ // Male Spieler
+ libvideo_change_color(0, 255, 0, 0);
+ libvideo_draw_rectangle(player.position.x, player.position.y,
+ player.size.x, player.size.y);
+
+ // Male Ball
+ libvideo_change_color(0, 0xab, 0xcd, 0xef);
+ libvideo_draw_rectangle(ball.position.x, ball.position.y,
+ ball.size.x, ball.size.y);
+
+ // Male Leben
+ for (int i = 0; i < player.lives; i++) {
+ libvideo_draw_rectangle(screen_width - 40 * i, 16, 20, 20);
+ }
+
+ libvideo_do_command_buffer();
+ libvideo_flip_buffers(front);
+}
+
+static bool init_game(void)
+{
+
+ /* Initialize player */
+ player.position = (Vector2){screen_width*1/10, screen_height/2};
+ player.size = (Vector2){20, screen_height/5};
+ player.lives = player_max_live;
+
+ /* Initialize ball */
+ ball.position = (Vector2){screen_width/2, screen_height/2};
+ ball.speed = (Vector2){0, 0};
+ ball.size = (Vector2){20, 20};
+ ball.active = false;
+
+ return true;
+}
+
+static void rpc_kbd_callback(pid_t pid, uint32_t cid, size_t data_size,
+ void* data)
+{
+ uint8_t* kbd_data = data;
+
+ if ((pid != keyboard.kbc_pid) || (data_size != 2)) {
+ return;
+ }
+
+ p();
+
+ if (kbd_data[0] == KEYCODE_ARROW_UP) {
+ update_key(&keyboard.arrow_up, !kbd_data[1]);
+ } else if (kbd_data[0] == KEYCODE_ARROW_DOWN) {
+ update_key(&keyboard.arrow_down, !kbd_data[1]);
+ } else if (kbd_data[0] == KEYCODE_ENTER) {
+ update_key(&keyboard.enter, !kbd_data[1]);
+ } else if (kbd_data[0] == KEYCODE_ESC) {
+ update_key(&keyboard.escape, !kbd_data[1]);
+ }
+
+ v();
+
+}
+
+static bool init_keyboard(void)
+{
+ // RPC-Handler fuer die Callbacks von KBD einrichten
+ register_message_handler(KBD_RPC_CALLBACK, rpc_kbd_callback);
+
+ keyboard.kbc_pid = init_service_get("kbc");
+ if (!keyboard.kbc_pid) {
+ return false;
+ }
+
+ // Callback registrtrieren bei KBC
+ return rpc_get_dword(keyboard.kbc_pid, KBD_RPC_REGISTER_CALLBACK, 0, NULL);
+}
+
+static bool init_screen(void)
{
stdout = 0;
driver_context_t* main_context;
main_context = libvideo_create_driver_context("vesa");
if (!main_context) {
fprintf(stderr, "Konnte Grafiktreiberkontext nicht erstellen\n");
- return EXIT_FAILURE;
+ return false;
}
libvideo_use_driver_context(main_context);
libvideo_get_command_buffer(1024);
@@ -85,75 +341,58 @@ int main(int argc, char** argv)
printf("Farbe gesetzt.\n");
- if (libvideo_change_display_resolution(0, 640, 480, 24) != 0) {
+ if (libvideo_change_display_resolution(0, screen_width,
+ screen_height, 24) != 0)
+ {
printf("Modus setzen fehlgeschlagen\n");
- return -1;
+ return false;
}
printf("Modus gesetzt.\n");
- video_bitmap_t *front;
front = libvideo_get_frontbuffer_bitmap(0);
int buffers = libvideo_request_backbuffers(front, 2);
printf("Got frontbuffer. %d Backbuffer.\n", buffers);
- int angle = 0;
- int speed = 100;
+ libvideo_change_target(front);
+ return true;
+}
- int x = 1024/2;
- int y = 768/2;
+static void close_screen(void)
+{
+ libvideo_close_upload_buffer(front);
+ libvideo_destroy_bitmap(front);
+ libvideo_restore_text_mode();
+}
+static void run(void)
+{
+ uint64_t time_last_update = get_tick_count();
+ uint64_t delta_time = 0;
- int dx, dy;
+ while (!game_over) {
- int frames = 0;
+ uint64_t current_time = get_tick_count();
+ delta_time += current_time - time_last_update;
+ time_last_update = current_time;
- uint64_t start = get_tick_count();
+ while (delta_time >= time_per_frame) {
+ delta_time -= time_per_frame;
+ update_player();
+ update_ball();
+ }
+ render();
+ }
+ close_screen();
+}
- int oldsec = 0;
+int main(int argc, char** argv)
+{
+ init_screen();
+ init_keyboard();
+ init_game();
- libvideo_change_target(front);
+ run();
- while (1) {
-// libvideo_change_target(back);
- libvideo_change_color(0,0,0,0);
- libvideo_draw_rectangle(0,0,1024,768);
-
- libvideo_change_color(0, 255, 0, 0);
- libvideo_draw_rectangle(0,0,1024,20);
- libvideo_draw_rectangle(0, 748, 1024, 20);
- libvideo_draw_rectangle(1004, 0, 20, 768);
-
- dx = sin(angle * M_PI / 180) * speed;
- dy = cos(angle * M_PI / 180) * speed;
-
- angle += 1;
- if (angle >= 360) angle=0;
-
- libvideo_change_color(0, 0xab, 0xcd, 0xef);
- libvideo_draw_rectangle(x-10+dx, y-10+dy, 20, 20);
-
- dx <<= 1;
- dy <<= 1;
- libvideo_change_color(0, 0, 255, 255);
- libvideo_draw_rectangle(x+dx, y+dy, 3, 3);
-
-// libvideo_change_target(front);
-// libvideo_draw_bitmap(back, 0,0 );
- libvideo_do_command_buffer();
- libvideo_flip_buffers(front);
-
- frames = frames + 1;
- uint64_t now = get_tick_count();
- uint64_t diff = now - start;
- // In Sek
- diff /= 1000000;
- if (diff > oldsec) {
- oldsec = diff;
- int fps = frames / diff;
- printf("Sek %d : %d Frames so far, Overall %d FPS\n", diff, fps, frames);
- }
- }
return 0;
-
}
--
2.29.2