From: notaz Date: Sun, 5 Apr 2015 23:55:58 +0000 (+0300) Subject: translate: initial struct parsing for member calls X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=ia32rtools.git;a=commitdiff_plain;h=865f1acac49aa6648651de91c1b27396f8679ef1 translate: initial struct parsing for member calls --- diff --git a/tools/protoparse.h b/tools/protoparse.h index 2647bba..511e337 100644 --- a/tools/protoparse.h +++ b/tools/protoparse.h @@ -50,6 +50,15 @@ struct parsed_proto { unsigned int has_retreg:1; }; +struct parsed_struct { + char name[256]; + struct { + int offset; + struct parsed_proto pp; + } members[64]; + int member_count; +}; + static const char *hdrfn; static int hdrfline = 0; @@ -58,6 +67,7 @@ static void pp_copy_arg(struct parsed_proto_arg *d, static int b_pp_c_handler(char *proto, const char *fname, int is_include, int is_osinc, int is_cinc); +static int struct_handler(FILE *fhdr, char *proto, int *line); static int do_protostrs(FILE *fhdr, const char *fname, int is_include) { @@ -120,8 +130,12 @@ static int do_protostrs(FILE *fhdr, const char *fname, int is_include) hdrfline = line; - ret = b_pp_c_handler(protostr, hdrfn, is_include, - is_osinc, is_cinc); + if (!strncmp(protostr, "struct", 6) + && strchr(protostr, '{') != NULL) + ret = struct_handler(fhdr, protostr, &line); + else + ret = b_pp_c_handler(protostr, hdrfn, + is_include, is_osinc, is_cinc); if (ret < 0) break; } @@ -165,7 +179,6 @@ static const char *known_type_mod[] = { "const", "signed", "unsigned", - "struct", "enum", "CONST", "volatile", @@ -225,7 +238,6 @@ static const char *ignored_keywords[] = { "WINADVAPI", }; -// returns ptr to char after type ends static int typecmp(const char *n, const char *t) { for (; *t != 0; n++, t++) { @@ -269,6 +281,14 @@ static int check_type(const char *name, struct parsed_type *type) n = skip_type_mod(name); + if (!strncmp(n, "struct", 6) && my_isblank(n[6])) { + type->is_struct = 1; + + n += 6; + while (my_isblank(*n)) + n++; + } + for (i = 0; i < ARRAY_SIZE(known_ptr_types); i++) { if (typecmp(n, known_ptr_types[i])) continue; @@ -351,7 +371,18 @@ static int parse_protostr(char *protostr, struct parsed_proto *pp) p = sskip(p + 2); } - // strip unneeded stuff + // allow start of line comment + if (p[0] == '/' && p[1] == '*') { + p = strstr(p + 2, "*/"); + if (p == NULL) { + printf("%s:%d: multiline comments unsupported\n", + hdrfn, hdrfline); + return -1; + } + p = sskip(p + 2); + } + + // we need remaining hints in comments, so strip / * for (p1 = p; p1[0] != 0 && p1[1] != 0; p1++) { if ((p1[0] == '/' && p1[1] == '*') || (p1[0] == '*' && p1[1] == '/')) @@ -662,6 +693,77 @@ static int pp_name_cmp(const void *p1, const void *p2) return strcmp(pp1->name, pp2->name); } +static int ps_name_cmp(const void *p1, const void *p2) +{ + const struct parsed_struct *ps1 = p1, *ps2 = p2; + return strcmp(ps1->name, ps2->name); +} + +// parsed struct cache +static struct parsed_struct *ps_cache; +static int ps_cache_size; +static int ps_cache_alloc; + +static int struct_handler(FILE *fhdr, char *proto, int *line) +{ + struct parsed_struct *ps; + char lstr[256], *p; + int offset = 0; + int m = 0; + int ret; + + if (ps_cache_size >= ps_cache_alloc) { + ps_cache_alloc = ps_cache_alloc * 2 + 64; + ps_cache = realloc(ps_cache, ps_cache_alloc + * sizeof(ps_cache[0])); + my_assert_not(ps_cache, NULL); + memset(ps_cache + ps_cache_size, 0, + (ps_cache_alloc - ps_cache_size) + * sizeof(ps_cache[0])); + } + + ps = &ps_cache[ps_cache_size++]; + ret = sscanf(proto, "struct %255s {", ps->name); + if (ret != 1) { + printf("%s:%d: struct parse failed\n", hdrfn, *line); + return -1; + } + + while (fgets(lstr, sizeof(lstr), fhdr)) + { + (*line)++; + + p = sskip(lstr); + if (p[0] == '/' && p[1] == '/') + continue; + if (p[0] == '}') + break; + + if (m >= ARRAY_SIZE(ps->members)) { + printf("%s:%d: too many struct members\n", + hdrfn, *line); + return -1; + } + + hdrfline = *line; + ret = parse_protostr(p, &ps->members[m].pp); + if (ret < 0) { + printf("%s:%d: struct member #%d/%02x " + "doesn't parse\n", hdrfn, *line, + m, offset); + return -1; + } + ps->members[m].offset = offset; + offset += 4; + m++; + } + + ps->member_count = m; + + return 0; +} + +// parsed proto cache static struct parsed_proto *pp_cache; static int pp_cache_size; static int pp_cache_alloc; @@ -692,7 +794,7 @@ static int b_pp_c_handler(char *proto, const char *fname, return 0; } -static void build_pp_cache(FILE *fhdr) +static void build_caches(FILE *fhdr) { long pos; int ret; @@ -705,6 +807,7 @@ static void build_pp_cache(FILE *fhdr) exit(1); qsort(pp_cache, pp_cache_size, sizeof(pp_cache[0]), pp_name_cmp); + qsort(ps_cache, ps_cache_size, sizeof(ps_cache[0]), ps_name_cmp); fseek(fhdr, pos, SEEK_SET); } @@ -716,7 +819,7 @@ static const struct parsed_proto *proto_parse(FILE *fhdr, const char *sym, char *p; if (pp_cache == NULL) - build_pp_cache(fhdr); + build_caches(fhdr); if (sym[0] == '_') // && strncmp(fname, "stdc", 4) == 0) sym++; @@ -734,6 +837,41 @@ static const struct parsed_proto *proto_parse(FILE *fhdr, const char *sym, return pp_ret; } +static const struct parsed_proto *proto_lookup_struct(FILE *fhdr, + const char *type, int offset) +{ + struct parsed_struct ps_search, *ps; + int m; + + if (pp_cache == NULL) + build_caches(fhdr); + if (ps_cache_size == 0) + return NULL; + + while (my_isblank(*type)) + type++; + if (!strncmp(type, "struct", 6) && my_isblank(type[6])) + type += 7; + + if (sscanf(type, "%255s", ps_search.name) != 1) + return NULL; + + ps = bsearch(&ps_search, ps_cache, ps_cache_size, + sizeof(ps_cache[0]), ps_name_cmp); + if (ps == NULL) { + printf("%s: struct '%s' is missing\n", + hdrfn, ps_search.name); + return NULL; + } + + for (m = 0; m < ps->member_count; m++) { + if (ps->members[m].offset == offset) + return &ps->members[m].pp; + } + + return NULL; +} + static void pp_copy_arg(struct parsed_proto_arg *d, const struct parsed_proto_arg *s) { @@ -833,4 +971,6 @@ static inline void proto_release(struct parsed_proto *pp) if (pp->ret_type.name != NULL) free(pp->ret_type.name); free(pp); + + (void)proto_lookup_struct; } diff --git a/tools/translate.c b/tools/translate.c index dadf7a9..bec6d07 100644 --- a/tools/translate.c +++ b/tools/translate.c @@ -208,7 +208,8 @@ struct parsed_op { }; // datap: -// OP_CALL - parser proto hint (str) +// on start: function/data type hint (sctproto) +// after analysis: // (OPF_CC) - points to one of (OPF_FLAGS) that affects cc op // OP_PUSH - points to OP_POP in complex push/pop graph // OP_POP - points to OP_PUSH in simple push/pop pair @@ -641,7 +642,7 @@ static char *default_cast_to(char *buf, size_t buf_size, { buf[0] = 0; - if (!opr->is_ptr) + if (!opr->is_ptr || strchr(opr->name, '[')) return buf; if (opr->pp == NULL || opr->pp->type.name == NULL || opr->pp->is_fptr) @@ -3488,10 +3489,25 @@ static void resolve_branches_parse_calls(int opcnt) po->bt_i = -1; po->btj = NULL; + if (po->datap != NULL) { + pp = calloc(1, sizeof(*pp)); + my_assert_not(pp, NULL); + + ret = parse_protostr(po->datap, pp); + if (ret < 0) + ferr(po, "bad protostr supplied: %s\n", (char *)po->datap); + free(po->datap); + po->datap = NULL; + po->pp = pp; + } + if (po->op == OP_CALL) { pp = NULL; - if (po->operand[0].type == OPT_LABEL) { + if (po->pp != NULL) + pp = po->pp; + else if (po->operand[0].type == OPT_LABEL) + { tmpname = opr_name(po, 0); if (IS_START(tmpname, "loc_")) ferr(po, "call to loc_*\n"); @@ -3521,16 +3537,6 @@ static void resolve_branches_parse_calls(int opcnt) my_assert_not(pp, NULL); } } - else if (po->datap != NULL) { - pp = calloc(1, sizeof(*pp)); - my_assert_not(pp, NULL); - - ret = parse_protostr(po->datap, pp); - if (ret < 0) - ferr(po, "bad protostr supplied: %s\n", (char *)po->datap); - free(po->datap); - po->datap = NULL; - } if (pp != NULL) { if (pp->is_fptr) @@ -3807,36 +3813,11 @@ static void scan_prologue_epilogue(int opcnt) } } -static const struct parsed_proto *resolve_icall(int i, int opcnt, - int *pp_i, int *multi_src) -{ - const struct parsed_proto *pp = NULL; - int search_advice = 0; - - *multi_src = 0; - *pp_i = -1; - - switch (ops[i].operand[0].type) { - case OPT_REGMEM: - case OPT_LABEL: - case OPT_OFFSET: - pp = try_recover_pp(&ops[i], &ops[i].operand[0], &search_advice); - if (!search_advice) - break; - // fallthrough - default: - scan_for_call_type(i, &ops[i].operand[0], i + opcnt * 9, &pp, - pp_i, multi_src); - break; - } - - return pp; -} - // find an instruction that changed opr before i op // *op_i must be set to -1 by the caller -// *entry is set to 1 if one source is determined to be the caller +// *is_caller is set to 1 if one source is determined to be g_func arg // returns 1 if found, *op_i is then set to origin +// returns -1 if multiple origins are found static int resolve_origin(int i, const struct parsed_opr *opr, int magic, int *op_i, int *is_caller) { @@ -4015,6 +3996,96 @@ static int try_resolve_const(int i, const struct parsed_opr *opr, return -1; } +static const struct parsed_proto *resolve_icall(int i, int opcnt, + int *pp_i, int *multi_src) +{ + const struct parsed_proto *pp = NULL; + int search_advice = 0; + int offset = -1; + char name[256]; + char s_reg[4]; + int reg, len; + int ret; + + *multi_src = 0; + *pp_i = -1; + + switch (ops[i].operand[0].type) { + case OPT_REGMEM: + // try to resolve struct member calls + ret = sscanf(ops[i].operand[0].name, "%3s+%x%n", + s_reg, &offset, &len); + if (ret == 2 && len == strlen(ops[i].operand[0].name)) + { + reg = char_array_i(regs_r32, ARRAY_SIZE(regs_r32), s_reg); + if (reg >= 0) { + struct parsed_opr opr = OPR_INIT(OPT_REG, OPLM_DWORD, reg); + int j = -1; + ret = resolve_origin(i, &opr, i + opcnt * 19, &j, NULL); + if (ret != 1) + break; + if (ops[j].op == OP_MOV && ops[j].operand[1].type == OPT_REGMEM + && ops[j].operand[0].lmod == OPLM_DWORD + && ops[j].pp == NULL) // no hint + { + // allow one simple dereference (directx) + reg = char_array_i(regs_r32, ARRAY_SIZE(regs_r32), + ops[j].operand[1].name); + if (reg < 0) + break; + struct parsed_opr opr2 = OPR_INIT(OPT_REG, OPLM_DWORD, reg); + int k = -1; + ret = resolve_origin(j, &opr2, j + opcnt * 19, &k, NULL); + if (ret != 1) + break; + j = k; + } + if (ops[j].op != OP_MOV) + break; + if (ops[j].operand[0].lmod != OPLM_DWORD) + break; + if (ops[j].pp != NULL) { + // type hint in asm + pp = ops[j].pp; + } + else if (ops[j].operand[1].type == OPT_REGMEM) { + // allow 'hello[ecx]' - assume array of same type items + ret = sscanf(ops[j].operand[1].name, "%[^[][e%2s]", + name, s_reg); + if (ret != 2) + break; + pp = proto_parse(g_fhdr, name, g_quiet_pp); + } + else if (ops[j].operand[1].type == OPT_LABEL) + pp = proto_parse(g_fhdr, ops[j].operand[1].name, g_quiet_pp); + else + break; + if (pp == NULL) + break; + if (pp->is_func || pp->is_fptr || !pp->type.is_struct) { + pp = NULL; + break; + } + pp = proto_lookup_struct(g_fhdr, pp->type.name, offset); + } + break; + } + // fallthrough + case OPT_LABEL: + case OPT_OFFSET: + pp = try_recover_pp(&ops[i], &ops[i].operand[0], &search_advice); + if (!search_advice) + break; + // fallthrough + default: + scan_for_call_type(i, &ops[i].operand[0], i + opcnt * 9, &pp, + pp_i, multi_src); + break; + } + + return pp; +} + static struct parsed_proto *process_call_early(int i, int opcnt, int *adj_i) { @@ -8065,11 +8136,8 @@ do_pending_endp: parse_op(&ops[pi], words, wordc); - if (sctproto != NULL) { - if (ops[pi].op == OP_CALL || ops[pi].op == OP_JMP) - ops[pi].datap = sctproto; - sctproto = NULL; - } + ops[pi].datap = sctproto; + sctproto = NULL; pi++; } diff --git a/win32.hlist b/win32.hlist index 993b322..1f90f6e 100644 --- a/win32.hlist +++ b/win32.hlist @@ -1865,30 +1865,131 @@ DWORD WINAPI lineTranslateDialogA(HLINEAPP,DWORD,DWORD,HWND,LPCSTR); DWORD WINAPI lineUnhold(HCALL); DWORD WINAPI lineUnparkA(HLINE,DWORD,LPHCALL,LPCSTR); +struct IDirectDraw { + // IUnknown methods +/*00*/ HRESULT (WINAPI *QueryInterface)(void *this, REFIID riid, void** ppvObject); +/*04*/ ULONG (WINAPI *AddRef)(void *this); +/*08*/ ULONG (WINAPI *Release)(void *this); + // IDirectDraw methods +/*0c*/ int (WINAPI *Compact)(void *this); +/*10*/ int (WINAPI *CreateClipper)(void *this, DWORD dwFlags, LPDIRECTDRAWCLIPPER *lplpDDClipper, IUnknown *pUnkOuter); +/*14*/ int (WINAPI *CreatePalette)(void *this, DWORD dwFlags, LPPALETTEENTRY lpColorTable, LPDIRECTDRAWPALETTE *lplpDDPalette, IUnknown *pUnkOuter); // 14 +/*18*/ int (WINAPI *CreateSurface)(void *this, LPDDSURFACEDESC lpDDSurfaceDesc, LPDIRECTDRAWSURFACE *lplpDDSurface, IUnknown *pUnkOuter); +/*1c*/ int (WINAPI *DuplicateSurface)(void *this, LPDIRECTDRAWSURFACE lpDDSurface, LPDIRECTDRAWSURFACE *lplpDupDDSurface); +/*20*/ int (WINAPI *EnumDisplayModes)(void *this, DWORD dwFlags, LPDDSURFACEDESC lpDDSurfaceDesc, LPVOID lpContext, LPDDENUMMODESCALLBACK lpEnumModesCallback); +/*24*/ int (WINAPI *EnumSurfaces)(void *this, DWORD dwFlags, LPDDSURFACEDESC lpDDSD, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback); +/*28*/ int (WINAPI *FlipToGDISurface)(void *this); +/*2c*/ int (WINAPI *GetCaps)(void *this, LPDDCAPS lpDDDriverCaps, LPDDCAPS lpDDHELCaps); +/*30*/ int (WINAPI *GetDisplayMode)(void *this, LPDDSURFACEDESC lpDDSurfaceDesc); +/*34*/ int (WINAPI *GetFourCCCodes)(void *this, LPDWORD lpNumCodes, LPDWORD lpCodes); +/*38*/ int (WINAPI *GetGDISurface)(void *this, LPDIRECTDRAWSURFACE *lplpGDIDDSurface); +/*3c*/ int (WINAPI *GetMonitorFrequency)(void *this, LPDWORD lpdwFrequency); +/*40*/ int (WINAPI *GetScanLine)(void *this, LPDWORD lpdwScanLine); +/*44*/ int (WINAPI *GetVerticalBlankStatus)(void *this, BOOL *lpbIsInVB); +/*48*/ int (WINAPI *Initialize)(void *this, GUID *lpGUID); +/*4c*/ int (WINAPI *RestoreDisplayMode)(void *this); +/*50*/ int (WINAPI *SetCooperativeLevel)(void *this, HWND hWnd, DWORD dwFlags); +/*54*/ int (WINAPI *SetDisplayMode)(void *this, DWORD dwWidth, DWORD dwHeight, DWORD dwBPP); +/*58*/ int (WINAPI *WaitForVerticalBlank)(void *this, DWORD dwFlags, HANDLE hEvent); +}; + +struct IDirectDrawPalette { + // IUnknown methods +/*00*/ HRESULT (WINAPI *QueryInterface)(void *this, REFIID riid, void** ppvObject); +/*04*/ ULONG (WINAPI *AddRef)(void *this); +/*08*/ ULONG (WINAPI *Release)(void *this); + // IDirectDrawPalette methods +/*0c*/ int (WINAPI *GetCaps)(void *this, LPDWORD lpdwCaps); +/*10*/ int (WINAPI *GetEntries)(void *this, DWORD dwFlags, DWORD dwBase, DWORD dwNumEntries, LPPALETTEENTRY lpEntries); +/*14*/ int (WINAPI *Initialize)(void *this, LPDIRECTDRAW lpDD, DWORD dwFlags, LPPALETTEENTRY lpDDColorTable); +/*18*/ int (WINAPI *SetEntries)(void *this, DWORD dwFlags, DWORD dwStartingEntry, DWORD dwCount, LPPALETTEENTRY lpEntries); +}; + +struct IDirectDrawSurface { + // IUnknown methods +/*00*/ HRESULT (WINAPI *QueryInterface)(void *this, REFIID riid, void** ppvObject); +/*04*/ ULONG (WINAPI *AddRef)(void *this); +/*08*/ ULONG (WINAPI *Release)(void *this); + // IDirectDrawSurface methods +/*0c*/ int (WINAPI *AddAttachedSurface)(void *this, LPDIRECTDRAWSURFACE lpDDSAttachedSurface); +/*10*/ int (WINAPI *AddOverlayDirtyRect)(void *this, LPRECT lpRect); +/*14*/ int (WINAPI *Blt)(void *this, LPRECT lpDestRect, LPDIRECTDRAWSURFACE lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx); +/*18*/ int (WINAPI *BltBatch)(void *this, LPDDBLTBATCH lpDDBltBatch, DWORD dwCount, DWORD dwFlags); +/*1c*/ int (WINAPI *BltFast)(void *this, DWORD dwX, DWORD dwY, LPDIRECTDRAWSURFACE lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwTrans); +/*20*/ int (WINAPI *DeleteAttachedSurface)(void *this, DWORD dwFlags, LPDIRECTDRAWSURFACE lpDDSAttachedSurface); +/*24*/ int (WINAPI *EnumAttachedSurfaces)(void *this, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback); +/*28*/ int (WINAPI *EnumOverlayZOrders)(void *this, DWORD dwFlags, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpfnCallback); +/*2c*/ int (WINAPI *Flip)(void *this, LPDIRECTDRAWSURFACE lpDDSurfaceTargetOverride, DWORD dwFlags); +/*30*/ int (WINAPI *GetAttachedSurface)(void *this, LPDDSCAPS lpDDSCaps, LPDIRECTDRAWSURFACE *lplpDDAttachedSurface); +/*34*/ int (WINAPI *GetBltStatus)(void *this, DWORD dwFlags); +/*38*/ int (WINAPI *GetCaps)(void *this, LPDDSCAPS lpDDSCaps); +/*3c*/ int (WINAPI *GetClipper)(void *this, LPDIRECTDRAWCLIPPER *lplpDDClipper); +/*40*/ int (WINAPI *GetColorKey)(void *this, DWORD dwFlags, LPDDCOLORKEY lpDDColorKey); +/*44*/ int (WINAPI *GetDC)(void *this, HDC *lphDC); +/*48*/ int (WINAPI *GetFlipStatus)(void *this, DWORD dwFlags); +/*4c*/ int (WINAPI *GetOverlayPosition)(void *this, LPLONG lplX, LPLONG lplY); +/*50*/ int (WINAPI *GetPalette)(void *this, LPDIRECTDRAWPALETTE *lplpDDPalette); +/*54*/ int (WINAPI *GetPixelFormat)(void *this, LPDDPIXELFORMAT lpDDPixelFormat); +/*58*/ int (WINAPI *GetSurfaceDesc)(void *this, LPDDSURFACEDESC lpDDSurfaceDesc); +/*5c*/ int (WINAPI *Initialize)(void *this, LPDIRECTDRAW lpDD, LPDDSURFACEDESC lpDDSurfaceDesc); +/*60*/ int (WINAPI *IsLost)(void *this); +/*64*/ int (WINAPI *Lock)(void *this, LPRECT lpDestRect, LPDDSURFACEDESC lpDDSurfaceDesc, DWORD dwFlags, HANDLE hEvent); +/*68*/ int (WINAPI *ReleaseDC)(void *this, HDC hDC); +/*6c*/ int (WINAPI *Restore)(void *this); +/*70*/ int (WINAPI *SetClipper)(void *this, LPDIRECTDRAWCLIPPER lpDDClipper); +/*74*/ int (WINAPI *SetColorKey)(void *this, DWORD dwFlags, LPDDCOLORKEY lpDDColorKey); +/*78*/ int (WINAPI *SetOverlayPosition)(void *this, LONG lX, LONG lY); +/*7c*/ int (WINAPI *SetPalette)(void *this, LPDIRECTDRAWPALETTE lpDDPalette); +/*80*/ int (WINAPI *Unlock)(void *this, LPVOID lpSurfaceData); +/*84*/ int (WINAPI *UpdateOverlay)(void *this, LPRECT lpSrcRect, LPDIRECTDRAWSURFACE lpDDDestSurface, LPRECT lpDestRect, DWORD dwFlags, LPDDOVERLAYFX lpDDOverlayFx); +/*88*/ int (WINAPI *UpdateOverlayDisplay)(void *this, DWORD dwFlags); +/*8c*/ int (WINAPI *UpdateOverlayZOrder)(void *this, DWORD dwFlags, LPDIRECTDRAWSURFACE lpDDSReference); +}; + +struct IDirectSound { + // IUnknown methods +/*00*/ HRESULT (WINAPI *QueryInterface)(void *this, REFIID riid, void** ppvObject); +/*04*/ ULONG (WINAPI *AddRef)(void *this); +/*08*/ ULONG (WINAPI *Release)(void *this); + // IDirectSound methods +/*0c*/ int (WINAPI *CreateSoundBuffer)(void *this, LPCDSBUFFERDESC lpcDSBufferDesc, LPLPDIRECTSOUNDBUFFER lplpDirectSoundBuffer, IUnknown *pUnkOuter); +/*10*/ int (WINAPI *GetCaps)(void *this, LPDSCAPS lpDSCaps); +/*14*/ int (WINAPI *DuplicateSoundBuffer)(void *this, LPDIRECTSOUNDBUFFER lpDsbOriginal, LPLPDIRECTSOUNDBUFFER lplpDsbDuplicate); +/*18*/ int (WINAPI *SetCooperativeLevel)(void *this, HWND hwnd, DWORD dwLevel); +/*1c*/ int (WINAPI *Compact)(void *this); +/*20*/ int (WINAPI *GetSpeakerConfig)(void *this, LPDWORD lpdwSpeakerConfig); +/*24*/ int (WINAPI *SetSpeakerConfig)(void *this, DWORD dwSpeakerConfig); +/*28*/ int (WINAPI *Initialize)(void *this, LPCGUID lpcGuid); +}; + +struct IDirectSoundBuffer { + // IUnknown methods +/*00*/ HRESULT (WINAPI *QueryInterface)(void *this, REFIID riid, void** ppvObject); +/*04*/ ULONG (WINAPI *AddRef)(void *this); +/*08*/ ULONG (WINAPI *Release)(void *this); + // IDirectSoundBuffer methods +/*0c*/ int (WINAPI *GetCaps)(void *this, LPDSBCAPS lpDSBufferCaps); +/*10*/ int (WINAPI *GetCurrentPosition)(void *this, LPDWORD lpdwCurrentPlayCursor, LPDWORD lpdwCurrentWriteCursor); +/*14*/ int (WINAPI *GetFormat)(void *this, LPWAVEFORMATEX lpwfxFormat, DWORD dwSizeAllocated, LPDWORD lpdwSizeWritten); +/*18*/ int (WINAPI *GetVolume)(void *this, LPLONG lplVolume); +/*1c*/ int (WINAPI *GetPan)(void *this, LPLONG lplpan); +/*20*/ int (WINAPI *GetFrequency)(void *this, LPDWORD lpdwFrequency); +/*24*/ int (WINAPI *GetStatus)(void *this, LPDWORD lpdwStatus); +/*28*/ int (WINAPI *Initialize)(void *this, LPDIRECTSOUND lpDirectSound, LPCDSBUFFERDESC lpcDSBufferDesc); +/*2c*/ int (WINAPI *Lock)(void *this, DWORD dwOffset, DWORD dwBytes, LPVOID *ppvAudioPtr1, LPDWORD pdwAudioBytes1, LPVOID *ppvAudioPtr2, LPDWORD pdwAudioBytes2, DWORD dwFlags); +/*30*/ int (WINAPI *Play)(void *this, DWORD dwReserved1, DWORD dwReserved2, DWORD dwFlags); +/*34*/ int (WINAPI *SetCurrentPosition)(void *this, DWORD dwNewPosition); +/*38*/ int (WINAPI *SetFormat)(void *this, LPCWAVEFORMATEX lpcfxFormat); +/*3c*/ int (WINAPI *SetVolume)(void *this, LONG lVolume); +/*40*/ int (WINAPI *SetPan)(void *this, LONG lPan); +/*44*/ int (WINAPI *SetFrequency)(void *this, DWORD dwFrequency); +/*48*/ int (WINAPI *Stop)(void *this); +/*4c*/ int (WINAPI *Unlock)(void *this, LPVOID pvAudioPtr1, DWORD dwAudioBytes1, LPVOID pvAudioPtr2, DWORD dwAudioPtr2); +/*50*/ int (WINAPI *Restore)(void *this); +}; // sctproto: int (__stdcall *Direct*Create)(void *, void *, void *) // 08 sctproto: int (WINAPI *dx_Release)(void *iface) -// IDirectDraw -// 14 sctproto: int (WINAPI *ddraw1_CreatePalette)(void *iface, DWORD flags, PALETTEENTRY *entries, void **palette, void *) -// 18 sctproto: int (WINAPI *ddraw1_CreateSurface)(void *iface, void *surface_desc, void **surface, void *) -// 2C sctproto: int (WINAPI *ddraw1_GetCaps)(void *iface, void *driver_caps, void *hel_caps) -// 38 sctproto: int (WINAPI *ddraw1_GetGDISurface)(void *iface, void **surface) -// 44 sctproto: int (WINAPI *ddraw1_GetVerticalBlankStatus)(void *iface, BOOL *status) -// 50 sctproto: int (WINAPI *ddraw1_SetCooperativeLevel)(void *iface, HWND window, DWORD flags) -// 54 sctproto: int (WINAPI *ddraw1_SetDisplayMode)(void *iface, DWORD width, DWORD height, DWORD bpp) -// 58 sctproto: int (WINAPI *ddraw1_WaitForVerticalBlank)(void *iface, DWORD flags, HANDLE event) -// IDirectDrawPalette -// 10 sctproto: int (WINAPI *palette_GetEntries)(void *, DWORD flags, DWORD start, DWORD count, PALETTEENTRY *entries) -// 18 sctproto: int (WINAPI *palette_SetEntries)(void *, DWORD flags, DWORD start, DWORD count, PALETTEENTRY *entries) -// IDirectDrawSurface -// 14 sctproto: int (WINAPI *surface1_Blt)(void *, RECT *, void *, RECT *, DWORD, void *) -// 30 sctproto: int (WINAPI *surface1_GetAttachedSurface)(void *, void *caps, void **attachment) -// 38 sctproto: int (WINAPI *surface1_GetCaps)(void *iface, void *caps) -// 54 sctproto: int (WINAPI *surface1_GetPixelFormat)(void *iface, void *fmt) -// 64 sctproto: int (WINAPI *surface1_Lock)(void *, void *, void *, DWORD, HANDLE) -// 6C sctproto: int (WINAPI *surface1_Restore)(void *) -// 7C sctproto: int (WINAPI *surface1_SetPalette)(void *iface, void *palette) -// 80 sctproto: int (WINAPI *surface1_Unlock)(void *, void *) // IDirectSound8 // 0C sctproto: int (WINAPI *dsound_CreateSoundBuffer)(void *iface, void *dsbd, void **ppdsb, void *lpunk) // 18 sctproto: int (WINAPI *dsound_SetCooperativeLevel)(void *iface, HWND hwnd, DWORD level)