diff --git a/src/audio.h b/src/audio.h
new file mode 100644
index 0000000000..1388be093d
--- /dev/null
+++ b/src/audio.h
@@ -0,0 +1,57 @@
+/*****************************************************************************
+ * Copyright (c) 2014 Ted John
+ * OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+ *
+ * This file is part of OpenRCT2.
+ *
+ * OpenRCT2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *****************************************************************************/
+
+#ifndef _AUDIO_H_
+#define _AUDIO_H_
+
+#include
+
+/**
+ * Represents a single directsound device.
+ */
+typedef struct {
+ GUID guid;
+ CHAR desc[256];
+ CHAR drvname[256];
+} rct_dsdevice;
+
+/**
+ * Represents a prepared sound.
+ */
+typedef struct {
+ LPDIRECTSOUNDBUFFER dsbuffer;
+ int id;
+ int has_caps;
+ int var_0C;
+ int var_10;
+} rct_sound;
+
+void get_dsound_devices();
+int sound_prepare(int sound_id, rct_sound *sound, int var_8, int var_c);
+int sound_play(rct_sound* sound, int looping, int volume, int pan, int frequency);
+void sound_stop(rct_sound *sound);
+
+typedef enum {
+ RCT2_SOUND_SCREAM = 11,
+ RCT2_SOUND_CHAINLIFT = 56,
+ RCT2_SOUND_TRACKFRICTION = 57,
+} RCT2_SOUND;
+
+#endif
\ No newline at end of file
diff --git a/src/gfx.c b/src/gfx.c
new file mode 100644
index 0000000000..54512d6ba4
--- /dev/null
+++ b/src/gfx.c
@@ -0,0 +1,120 @@
+/*****************************************************************************
+ * Copyright (c) 2014 Ted John
+ * OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+ *
+ * This file is part of OpenRCT2.
+ *
+ * OpenRCT2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *****************************************************************************/
+
+#include "addresses.h"
+#include "gfx.h"
+#include "rct2.h"
+
+/**
+* Clears the screen with the specified colour.
+* rct2: 0x00678A9F
+*/
+void gfx_clear(rct_drawpixelinfo *dpi, int colour)
+{
+ int y, w, h;
+ char* ptr;
+
+ w = dpi->width >> dpi->var_0F;
+ h = dpi->height >> dpi->var_0F;
+
+ ptr = dpi->bits;
+ for (y = 0; y < h; y++) {
+ memset(ptr, colour, w);
+ ptr += w + dpi->pitch;
+ }
+}
+
+/**
+*
+* rct2: 0x00678AD4
+* left (ax)
+* top (cx)
+* right (bx)
+* bottom (dx)
+* colour (ebp)
+*/
+void gfx_fill_rect(rct_drawpixelinfo *dpi, int left, int top, int right, int bottom, int colour)
+{
+ RCT2_CALLPROC_X(0x00678AD4, left, right, top, bottom, 0, dpi, colour);
+}
+
+/**
+*
+* rct2: 0x0067A28E
+* image_id (ebx)
+* x (cx)
+* y (dx)
+*/
+void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y)
+{
+ RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, dpi, 0);
+}
+
+/**
+*
+* rct2: 0x00683854
+* a1 (ebx)
+* product (cl)
+*/
+void gfx_transpose_palette(int pal, unsigned char product)
+{
+ int eax, ebx, ebp;
+ uint8* esi, *edi;
+
+ ebx = pal * 16;
+ esi = (uint8*)(*((int*)(0x009EBD28 + ebx)));
+ ebp = *((short*)(0x009EBD2C + ebx));
+ eax = *((short*)(0x009EBD30 + ebx)) * 4;
+ edi = (uint8*)0x01424680 + eax;
+
+ for (; ebp > 0; ebp--) {
+ edi[0] = (esi[0] * product) >> 8;
+ edi[1] = (esi[1] * product) >> 8;
+ edi[2] = (esi[2] * product) >> 8;
+ esi += 3;
+ edi += 4;
+ }
+
+ RCT2_CALLPROC_3(0x00405595, int, int, int, 0x01424680, 10, 236);
+}
+
+/**
+* Draws i formatted text string centred at i specified position.
+* rct2: 0x006C1D6C
+* dpi (edi)
+* format (bx)
+* x (cx)
+* y (dx)
+* colour (al)
+* args (esi)
+*/
+void gfx_draw_string_centred(rct_drawpixelinfo *dpi, int format, int x, int y, int colour, void *args)
+{
+ RCT2_CALLPROC_X(0x006C1D6C, colour, format, x, y, args, dpi, 0);
+}
+
+/**
+*
+* rct2: 0x006ED7E5
+*/
+void gfx_invalidate_screen()
+{
+ RCT2_CALLPROC_EBPSAFE(0x006ED7E5);
+}
\ No newline at end of file
diff --git a/src/gfx.h b/src/gfx.h
new file mode 100644
index 0000000000..ab908e7fbb
--- /dev/null
+++ b/src/gfx.h
@@ -0,0 +1,58 @@
+/*****************************************************************************
+* Copyright (c) 2014 Ted John
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* This file is part of OpenRCT2.
+*
+* OpenRCT2 is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see .
+*****************************************************************************/
+
+#ifndef _GFX_H_
+#define _GFX_H_
+
+typedef struct {
+ char* bits; // 0x00
+ short x; // 0x04
+ short y; // 0x06
+ short width; // 0x08
+ short height; // 0x0A
+ short pitch; // 0x0C
+ char pad_0E; // 0x0E
+ char var_0F; // 0x0F
+} rct_drawpixelinfo;
+
+void gfx_clear(rct_drawpixelinfo *dpi, int colour);
+void gfx_fill_rect(rct_drawpixelinfo *dpi, int left, int top, int right, int bottom, int colour);
+void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y);
+void gfx_draw_string(rct_drawpixelinfo *dpi, char *text, int colour, int x, int y);
+void gfx_transpose_palette(int pal, unsigned char product);
+
+void gfx_draw_string_left(rct_drawpixelinfo *dpi, int format, void *args, int colour, int x, int y);
+void gfx_draw_string_left_clipped(rct_drawpixelinfo *dpi, int format, void *args, int colour, int x, int y, int width);
+void gfx_draw_string_centred_clipped(rct_drawpixelinfo *dpi, int format, void *args, int colour, int x, int y, int width);
+void gfx_draw_string_right(rct_drawpixelinfo *dpi, int format, void *args, int colour, int x, int y);
+void gfx_draw_string_centred(rct_drawpixelinfo *dpi, int format, int x, int y, int colour, void *args);
+int gfx_draw_string_centred_wrapped(rct_drawpixelinfo *dpi, void *args, int x, int y, int width, int format, int colour);
+int gfx_draw_string_left_wrapped(rct_drawpixelinfo *dpi, void *format, int x, int y, int width, int colour, int unknown);
+
+int gfx_get_string_width(char *buffer);
+int clip_text(char *buffer, int width);
+void gfx_fill_rect_inset(rct_drawpixelinfo *dpi, short left, short top, short right, short bottom, int colour, short _si);
+
+void gfx_set_dirty_blocks(short left, short top, short right, short bottom);
+void gfx_draw_dirty_blocks();
+void gfx_redraw_screen_rect(short left, short top, short right, short bottom);
+void gfx_invalidate_screen();
+
+#endif
\ No newline at end of file
diff --git a/src/osinterface.c b/src/osinterface.c
index 74a32f407e..4f6e02728b 100644
--- a/src/osinterface.c
+++ b/src/osinterface.c
@@ -42,6 +42,7 @@ static SDL_Window *_window;
static SDL_Surface *_surface;
static SDL_Palette *_palette;
+static int _screenBufferSize;
static void *_screenBuffer;
void osinterface_init()
@@ -94,6 +95,8 @@ static void osinterface_create_window()
static void osinterface_resize(int width, int height)
{
rct_drawpixelinfo *screenDPI;
+ int newScreenBufferSize;
+ void *newScreenBuffer;
if (_surface != NULL)
SDL_FreeSurface(_surface);
@@ -105,11 +108,19 @@ static void osinterface_resize(int width, int height)
SDL_SetSurfacePalette(_surface, _palette);
- if (_screenBuffer != NULL)
+ newScreenBufferSize = _surface->pitch * _surface->h;
+ newScreenBuffer = malloc(newScreenBufferSize);
+ if (_screenBuffer == NULL) {
+ memset(newScreenBuffer, 0, newScreenBufferSize);
+ } else {
+ memcpy(newScreenBuffer, _screenBuffer, _screenBufferSize);
+ if (newScreenBufferSize - _screenBufferSize > 0)
+ memset((uint8*)newScreenBuffer + _screenBufferSize, 0, newScreenBufferSize - _screenBufferSize);
free(_screenBuffer);
+ }
- _screenBuffer = malloc(_surface->pitch * _surface->h);
- memset(_screenBuffer, 0, _surface->pitch * _surface->h);
+ _screenBuffer = newScreenBuffer;
+ _screenBufferSize = newScreenBufferSize;
RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, sint16) = width;
RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, sint16) = height;